keystore.cpp revision 86b16e8c0d353af97f0411917789308dba417295
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 Root/* 27607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 27707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 27807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 27907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 28007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 28107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 28707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 28807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 29007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 29307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 29407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 29507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 29607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 29707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 29807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 29907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 30007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 30107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 30207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 30307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 30407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 30607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 315150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 3165281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 317150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 328150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 329150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 330150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 331150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 343150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 350150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 351150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3585187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 370822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 371f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 375822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 376822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 377822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 378822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 379822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 380822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 381822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 382822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 383822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 384822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 385822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 386822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 387822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 388822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 390822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 391822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 392f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 395822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 397822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 402822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 403d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 404822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 405822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 406822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 407822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 408822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 409f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 410822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 41307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 41407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 420822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 42107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 422822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 423f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 424f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4335187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4375187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4415187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4425187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4435187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4445187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4455187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 449822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 450822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 452822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 453f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 454f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 455f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 456f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 457f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 458f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 459f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 460f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 461f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 462f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 463f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 464f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 465f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 466f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 467f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 468f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 46917208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 47017208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 47117208e0de5a42722901d803118745cca25fd10c1Kenny Root } 47217208e0de5a42722901d803118745cca25fd10c1Kenny Root 47317208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 47417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 47517208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 47617208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 47717208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 47817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 47917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 48017208e0de5a42722901d803118745cca25fd10c1Kenny Root 481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 483822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 486822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 490822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 493f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 494f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 495f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 496f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 497f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 498f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 499f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 500f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 501f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 502f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 503f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 504f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 521f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 522f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 523f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 524f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 525f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 526f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 527f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 528f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 534150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 535150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 536150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 537150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 545150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 549150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 550150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 551150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 552150ca934edb745de3666a6492b039900df228ff0Kenny Root } 553150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 555a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 556f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 557f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 558150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 559150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 569f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 570f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 571f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 572f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 573f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 580f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 583f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 584f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 585f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 586f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 587f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 588f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 589f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 593f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 595f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 596f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 597f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 598f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 599f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 61107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 618655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 619655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 620655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 621655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 622655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 623655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 62470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 625655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 626655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 627655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 628655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 62970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 630655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 631655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 632655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 633655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 634655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 635655b958eb2180c7c06889f83f606d23421bf038cKenny Root 636655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 64170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 642655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 643655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 644655b958eb2180c7c06889f83f606d23421bf038cKenny Root 645655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 646655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 647655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 648655b958eb2180c7c06889f83f606d23421bf038cKenny Root 649655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 650655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 651655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 652655b958eb2180c7c06889f83f606d23421bf038cKenny Root 653655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 654655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 655655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 656655b958eb2180c7c06889f83f606d23421bf038cKenny Root 657655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 658655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 659655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 660655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 661655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6645187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6685187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 672655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 673655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 674655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 675655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 676655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 67770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 67870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 679655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 680655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 683655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 68807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 691655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 696822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 697f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 700655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 701655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 702150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 725f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 726f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 728f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 732a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 733655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 736655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 758655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 759655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 760655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 762655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 763655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 767655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 769655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 772655b958eb2180c7c06889f83f606d23421bf038cKenny Root 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 775655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 776655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 777655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 778655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 779655b958eb2180c7c06889f83f606d23421bf038cKenny Root 780655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 781655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 782655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 783655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 784655b958eb2180c7c06889f83f606d23421bf038cKenny Root 785655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's UID. 786655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 787655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 788655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 789655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 790655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 791655b958eb2180c7c06889f83f606d23421bf038cKenny Root 792655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip if this is not our user. 793655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_user_id(thisUid) != mUserId) { 794655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 795655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 796655b958eb2180c7c06889f83f606d23421bf038cKenny Root 797655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 803655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 804655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 805655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 806655b958eb2180c7c06889f83f606d23421bf038cKenny Root 807655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 808655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 809655b958eb2180c7c06889f83f606d23421bf038cKenny Root 810655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 811655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 812655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 813655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 814655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 815655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 816655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 817655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 818655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 819655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 820655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 821655b958eb2180c7c06889f83f606d23421bf038cKenny Root 822655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 823655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 824655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 825655b958eb2180c7c06889f83f606d23421bf038cKenny Root 826655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 827655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 828655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 829655b958eb2180c7c06889f83f606d23421bf038cKenny Root 830655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 831655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 832655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 834655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 835655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 836655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 837655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 838655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 839655b958eb2180c7c06889f83f606d23421bf038cKenny Root 840655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 841655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 843655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 844655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 845655b958eb2180c7c06889f83f606d23421bf038cKenny Root 846655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 847655b958eb2180c7c06889f83f606d23421bf038cKenny Root 848655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 850655b958eb2180c7c06889f83f606d23421bf038cKenny Root 851655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 852655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root 854655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 856655b958eb2180c7c06889f83f606d23421bf038cKenny Root 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 859655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root 861655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 862655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 863655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 864655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 865655b958eb2180c7c06889f83f606d23421bf038cKenny Root 866655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 867655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.erase(it); 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 924a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 930a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 936a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (userState == NULL) { 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 956a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 957a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 958a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 959a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 960a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 963655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(filename, sizeof(filename), "%u_", uid); 964655b958eb2180c7c06889f83f606d23421bf038cKenny Root 965a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(file->d_name, filename, n)) { 977a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 978a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 979a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 980a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 981a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 982a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 983a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 984a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 985655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 986655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 987655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 988655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 989a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 990a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 991655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 992655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 993f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 994f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 995822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 996822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 997822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 998822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 999822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 100007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1001cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1002cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1003cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1004cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 1007f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1008f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1009cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1010cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1011cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1012822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1013822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 101417208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 101517208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 101617208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 101717208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 101817208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 101917208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 102017208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 102117208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 102217208e0de5a42722901d803118745cca25fd10c1Kenny Root uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 102317208e0de5a42722901d803118745cca25fd10c1Kenny Root 102417208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 102517208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 102617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 102717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid); 102817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 102917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 103017208e0de5a42722901d803118745cca25fd10c1Kenny Root 1031d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1032822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1033822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1034822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1035822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1036822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1037a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1038a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1039655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1040655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1041f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1042f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1043a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1044a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 104507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1046655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1047655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1048655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 104907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1050a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 105270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 105370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 105470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 105507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1056655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1057655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1058655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1059655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1060655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1061655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1062655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1063655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 106470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 106570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 106670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 106770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1068a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1069a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 107070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1072f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1073f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1074822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1075822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1076822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1077822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1078822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1079822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1080822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1081822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1082822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 108317208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 108407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1085822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 108617208e0de5a42722901d803118745cca25fd10c1Kenny Root // If this is an old device HAL, try to fall back to an old version 108717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (mDevice->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_2) { 108817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength); 108917208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 109017208e0de5a42722901d803118745cca25fd10c1Kenny Root } 109117208e0de5a42722901d803118745cca25fd10c1Kenny Root 109217208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 109317208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 109417208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 109517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1096822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1097822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1098822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1099822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1101f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 110217208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1103f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1104655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1106822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 11071b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 11081b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 11091b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 11101b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 11111b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11121b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 11131b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 11141b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 11151b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 11161b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 11171b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 11181b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 11191b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11208ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 11218ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 112486b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 1125a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1128655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1129655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1131655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1132655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1133655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 113486b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 1135655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1136655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1137655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1138655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1139655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 114070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1141655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 114286b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1143655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 114486b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1145655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1146655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1147655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 114886b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(), 114986b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1150655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1151655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1154655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1155655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1158655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1159655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1160655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1161655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1162655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1163655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1164655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1165655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1166655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1167655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1168655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1169655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1171655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1172655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1173655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1174655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1175655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1176655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1177655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1178655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1179a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1180655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1181655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1182a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1183a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1184655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1185655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1186655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1187655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1188655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1189655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1190655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1191655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1192655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1193655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1194655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1195655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1196655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1198655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1200a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1201655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1202655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1203655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 12041b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1205655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 120607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1207655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1209655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1210655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1211655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 121270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1213655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1215655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 121670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1217655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1220655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1221655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1222655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 122370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1224655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 122570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 122670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 122770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 122870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 122970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1231822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1232822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1233822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1234822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1235655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1236655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1237822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1238822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1239822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1240822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1241822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1242822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1243822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1244822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1245822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1246655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1247822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1248822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1249822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1250822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1251822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1252f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1253f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1254f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1255f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1256f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1257f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1258f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1259f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1260f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1261822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1262822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1263822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1264cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1268822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1269cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1270cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1271822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1272822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1273822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1274822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1275822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1276822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1277822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1278822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1279655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1280822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1281822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1282822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1283822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1284822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1285822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1286822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1287822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1288822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1289822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1298822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1299822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 130070c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 130170c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1302822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1303822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1304822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1305822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1307f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1308f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1309822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1310822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1311822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1312822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1313655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1314822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 131570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1316655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1317655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1318655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1319655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1320655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1321655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1322655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1323655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1324655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1325655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1326655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 132770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 132870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1329655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1330655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1331655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1332655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1333655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1334655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1336655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1337655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1338655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1339655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1340655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 134170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1342655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1343655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 134470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 134570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1346655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1347655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1348655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1349655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1350655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1355655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1359655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1360655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1364655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1366655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1368655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1370655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1372655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1373655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1374655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1376655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1385655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1387655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1391655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1392655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1409655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 141570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 141770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1418655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 142070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14211b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 14221b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 142307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 142407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 142507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 142607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 142807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 142907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 143107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 143207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 143307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 143507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1436d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1437d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 1438d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 143907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 144007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1442655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 144507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1446d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1447d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1448d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 144907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 145007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 145207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 145307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1454494689083467ec372a58f094f041c8f102f39393Kenny Root 1455655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1456494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 145707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1458655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 145907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 146007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 146107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 146207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 146407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 146507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 146607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 146807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1471f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1472f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1473d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1474d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1475d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 147607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 147707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 147807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1479f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1480f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1481f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1482f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1483f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1484f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1485494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1486494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1487494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1488b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1489b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1490b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1492655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 149307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1495655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 1496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1498494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1499d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1500d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1501d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 150207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 150407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1505494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1506494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1507494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1508b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1509b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1510b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 151107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1512655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1513298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1515655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1516655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 151907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1521298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1522298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1523494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1524d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1525d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1526d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 152707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 152807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1530494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1531494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1532494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1533b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1534b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1535b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 153607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1537655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1539655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1543298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1544298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1545494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1546d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1547d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1548d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 155007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1552494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1553494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1554494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1555b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1556b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1557b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1558655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1559655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 156207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1566655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 156807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 157007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1571655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1572655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1574655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1575655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1576655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1578655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1579655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1581655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 158407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 159207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 159707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 159807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1599298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1600298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 160107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1602d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1603d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1604d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 160507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 160607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1608655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 161007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 161107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 161207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 161307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 161507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 161607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 161707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 162007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 162207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 162507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 163107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 163307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 163407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 163507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1637d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1638d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1639d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 164307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1645655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 164607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 164707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 165107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1652655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 165307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 165507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1656655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 165707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 166207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1663d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1664d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1665d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 166607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 166707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1669655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16709d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 167107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 167207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 167307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 167470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1675655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 167607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 167770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1680d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1681d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1682d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 168307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1686655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16879d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 168807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 169470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 169570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1697d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1698d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1699d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 170007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 170270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1703655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 170470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 170570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 170696427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 170796427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1708d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1709d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1710d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 171107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1714494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1715494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1716494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1717b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1718b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1719b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1720655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1721f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1722f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 172307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 172607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 172807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 172917208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 173070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 173207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 173307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 173407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 173707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 173807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 174017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 174196427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 174296427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 174396427baf0094d50047049d329b0779c3c910402cKenny Root 174496427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 174596427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 174696427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 174796427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 174896427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 174996427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 175096427baf0094d50047049d329b0779c3c910402cKenny Root } 175196427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 175296427baf0094d50047049d329b0779c3c910402cKenny Root 175396427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 175496427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 175596427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 175696427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 175796427baf0094d50047049d329b0779c3c910402cKenny Root 175896427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 175996427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 176096427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 176196427baf0094d50047049d329b0779c3c910402cKenny Root 176296427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 176396427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 176496427baf0094d50047049d329b0779c3c910402cKenny Root 176596427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 176696427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 176796427baf0094d50047049d329b0779c3c910402cKenny Root } else { 176896427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 176996427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 177096427baf0094d50047049d329b0779c3c910402cKenny Root } 177196427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 177296427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 177396427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 177496427baf0094d50047049d329b0779c3c910402cKenny Root } 177596427baf0094d50047049d329b0779c3c910402cKenny Root 177617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) { 177717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 177817208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 177917208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 178017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 178117208e0de5a42722901d803118745cca25fd10c1Kenny Root } 178217208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 178396427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 178496427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 178596427baf0094d50047049d329b0779c3c910402cKenny Root 178696427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 178796427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 178896427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 178996427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 179096427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 179196427baf0094d50047049d329b0779c3c910402cKenny Root } 179296427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 179396427baf0094d50047049d329b0779c3c910402cKenny Root 179417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) { 179517208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 179617208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 179717208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 179817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 179917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 180096427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 180196427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 180296427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 180396427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 180496427baf0094d50047049d329b0779c3c910402cKenny Root 180596427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 180696427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 180796427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 180896427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 180996427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 181096427baf0094d50047049d329b0779c3c910402cKenny Root } 181196427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 181296427baf0094d50047049d329b0779c3c910402cKenny Root 181396427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 181496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid number of arguments: %d", args->size()); 181596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 181696427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 181796427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 181896427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 181996427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 182096427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 182196427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 182296427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 182396427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 182496427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 182596427baf0094d50047049d329b0779c3c910402cKenny Root } 182696427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 182796427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 182896427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 182996427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 183096427baf0094d50047049d329b0779c3c910402cKenny Root } 183196427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 183296427baf0094d50047049d329b0779c3c910402cKenny Root } 183396427baf0094d50047049d329b0779c3c910402cKenny Root } 183496427baf0094d50047049d329b0779c3c910402cKenny Root 183596427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 183696427baf0094d50047049d329b0779c3c910402cKenny Root } else { 183796427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 183896427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 183996427baf0094d50047049d329b0779c3c910402cKenny Root } 184070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 184107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 184207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 184307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 184470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1845655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1846655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 184770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 184807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 184907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 185007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 185117208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 185217208e0de5a42722901d803118745cca25fd10c1Kenny Root 1853655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 185470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 185570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1856f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1857f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1858d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1859d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1860d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 186107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 186207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1864494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1865494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1866494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1867b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1868b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1869b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1870655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1871f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 187207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 187307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 187407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 187570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 187607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 187760898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 187870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1879f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mKeyStore->importKey(data, length, filename.string(), callingUid, flags); 188070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 188170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 188307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1884d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1885d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1886d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 188707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 188807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18899a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 189007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 189107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 189270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1893d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 189407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 189570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1896655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1897d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 189807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 189907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 190007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 190207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 190307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 190407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 190507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 190607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 190807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 190907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 191007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 191107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 191307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 191407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 191507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 191607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 191717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 191817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 191917208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 192017208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 192117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 192217208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 192317208e0de5a42722901d803118745cca25fd10c1Kenny Root } 192407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 192507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 192607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 192707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 192870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 192907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 193070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 193170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 193207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 193307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1934d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1935d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1936d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 193707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 193807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 193970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1940655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 19419d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 194207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 194307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 194407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 194607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 194707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 194807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 194970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1950655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1951494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 195207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 195307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 195407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 195570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 195607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 195707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 195807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 195907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 196107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 196207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 196307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 196507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 196607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 196707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 196870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 196917208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 197017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 197117208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 197217208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 197317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 197417208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 197517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 197607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 197707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 197807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 197907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 198007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 198270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 198407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 198507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 198707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 198807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 198907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 199007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 199107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 199207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 199407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 1995d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1996d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1997d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 199807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 199907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 200207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 200370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2004d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 200570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2006655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 200707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 200807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 200907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 201007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 201307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 201407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 201807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 201907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 202007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2021344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 202217208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 202317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 202417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 202517208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 202617208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 202717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 202817208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 202917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 203007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 203107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 203207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2033344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 203407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2035344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2036344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2037494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2038d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2039d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 2040d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 204107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 204207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2043344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2044494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2045494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2046494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2047b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2048b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2049b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 205007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2051655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 2052344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 205307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 2054655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 2055655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 205607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 205807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2059a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 2061a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 206207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 206717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 206807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 207007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2073a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 207407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2077a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 207807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 2079a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 208007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2082d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2083d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 2084d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 208507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 208607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2088655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20899d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 209007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 209107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 209207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2095655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 209607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2097655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2101655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2103a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 210407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2106d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2107d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 2108d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 210907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 211007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2112655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21139d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 211607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 211807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2119655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2121655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 212407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2125655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2126a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 212807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2129d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2130d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 2131d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 213236a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 213307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2136655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2138655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2139655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 214036a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2141a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 214207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2143655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2145655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 214636a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 214707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 214807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 214907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 215107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2153655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 215436a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 215736a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 215907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2160d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2161d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 21620225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2163d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!has_permission(callingUid, P_DUPLICATE)) { 2164d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 21650225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 21660225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21670225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2168655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21690225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2170d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 21710225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 21720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21730225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2174d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2175d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2176d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2177d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 21780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 21790225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21800225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2181d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2182d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2183d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21840225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2185d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2186d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2187d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2188d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2189d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2190d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21910225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2192d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2193d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2194d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2195d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21960225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21970225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2198d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2199655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2200d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2201d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2202655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, srcUid)); 22030225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2204655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2205655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 22060225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 22070225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22080225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2209d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2210655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2211655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 2212d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2213d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 22140225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2215d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2216655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, callingUid); 22170225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22180225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 22191b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 22201b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 22218ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 22228ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2223a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root int32_t clear_uid(int64_t targetUid) { 2224a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2225a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!has_permission(callingUid, P_CLEAR_UID)) { 2226a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2227a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2228a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2229a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2230655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 2231a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!isKeystoreUnlocked(state)) { 2232a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGD("calling clear_uid in state: %d", state); 2233a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return state; 2234a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2235a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2236a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2237a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2238655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2239a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2240a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2241a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2242655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(callingUid); 2243655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2244a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2245655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2246a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2247a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2248a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2249655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2250655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", static_cast<uid_t>(targetUid)); 2251a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2252a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2253a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2254a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2255a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2256655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2257655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2258a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2259a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2260a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2261655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2262655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2263655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2264655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2265655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2266655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2267655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2268655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2269a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2270655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2271a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2272655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, callingUid) 2273655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2274655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2275a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2276a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2277a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2278a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2279a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 228017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 2281a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2282a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2283655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2284a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2285a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2286a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2287a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 22885f53124250025d3113c9c598a2f101330144b10cKenny Root if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) { 2289a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2290655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2291a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2292a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2293a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2294a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2295a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2296a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2297a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 229807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 22999d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 23009d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 23019d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 23029d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 23039d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 23049d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 23059d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 23069d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 23079d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 230907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 231007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 231107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 231207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 231307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 232970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 233070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 233170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 233270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 233370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 233470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 233570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 233670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2337655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 233807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 233907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 234007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 234107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 234207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 234307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 234570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 234607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 234707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 234807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 234907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 235007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 235170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 235207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2355