keystore.cpp revision ee8068b9e7bfb2770635062fc9c2035be2142bd8
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 424ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 425ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 426ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 427ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 428ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4375187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4415187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4455187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4465187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4475187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4485187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4495187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 454822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 457f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 458f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 459f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 460f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 461f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 462f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 463f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 464f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 465f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 466f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 467f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 468f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 469f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 470f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 471f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 472f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 47317208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 47417208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 47517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 47617208e0de5a42722901d803118745cca25fd10c1Kenny Root 47717208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 47817208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 47917208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 48017208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 48117208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 48217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 48317208e0de5a42722901d803118745cca25fd10c1Kenny Root } 48417208e0de5a42722901d803118745cca25fd10c1Kenny Root 485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 486822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 490822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 493822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 495822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 496822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 497f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 498f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 499f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 500f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 501f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 502f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 503f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 504f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 505f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 506f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 507f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 508f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 525f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 526f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 527f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 528f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 529f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 530f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 531f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 532f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 538150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 539150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 540150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 541150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 549150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 553150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 554150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 555150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 556150ca934edb745de3666a6492b039900df228ff0Kenny Root } 557150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 560f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 561f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 562150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 563150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 573f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 574f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 575f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 576f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 577f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 584f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 587f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 588f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 589f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 593f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 595f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 596f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 597f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 598f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 599f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 600f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 601f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 602f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 603f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 61507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 622655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 623655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 624655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 625655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 626655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 627655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 62870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 629655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 630655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 631655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 632655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 63370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 634655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 635655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 636655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 637655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 638655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 639655b958eb2180c7c06889f83f606d23421bf038cKenny Root 640655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 64570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 646655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 647655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 648655b958eb2180c7c06889f83f606d23421bf038cKenny Root 649655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 650655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 651655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 652655b958eb2180c7c06889f83f606d23421bf038cKenny Root 653655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 654655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 655655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 656655b958eb2180c7c06889f83f606d23421bf038cKenny Root 657655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 658655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 659655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 660655b958eb2180c7c06889f83f606d23421bf038cKenny Root 661655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 662655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 663655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 664655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 665655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6685187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6725187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 676655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 677655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 678655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 679655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 680655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 68170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 68270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 683655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 684655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 687655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 69207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 695655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 700822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 701f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 704655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 705655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 706150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 729f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 730f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 732f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 737655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 762655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 763655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 767655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 768655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 770655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 771655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 776655b958eb2180c7c06889f83f606d23421bf038cKenny Root 777655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 779655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 780655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 781655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 782655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 783655b958eb2180c7c06889f83f606d23421bf038cKenny Root 784655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 785655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 786655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 787655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 788655b958eb2180c7c06889f83f606d23421bf038cKenny Root 789655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's UID. 790655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 791655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 792655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 793655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 794655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 795655b958eb2180c7c06889f83f606d23421bf038cKenny Root 796655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip if this is not our user. 797655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_user_id(thisUid) != mUserId) { 798655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 799655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 800655b958eb2180c7c06889f83f606d23421bf038cKenny Root 801655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 807655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 808655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 809655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 810655b958eb2180c7c06889f83f606d23421bf038cKenny Root 811655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 812655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 813655b958eb2180c7c06889f83f606d23421bf038cKenny Root 814655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 815655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 816655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 817655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 818655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 819655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 820655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 821655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 822655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 823655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 824655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 825655b958eb2180c7c06889f83f606d23421bf038cKenny Root 826655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 827655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 828655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 829655b958eb2180c7c06889f83f606d23421bf038cKenny Root 830655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 831655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 832655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root 834655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 835655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 836655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 837655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 838655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 839655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 840655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 841655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 843655b958eb2180c7c06889f83f606d23421bf038cKenny Root 844655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 845655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 846655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 847655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 848655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root 850655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 851655b958eb2180c7c06889f83f606d23421bf038cKenny Root 852655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 854655b958eb2180c7c06889f83f606d23421bf038cKenny Root 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 856655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 859655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root 861655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 862655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 863655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 864655b958eb2180c7c06889f83f606d23421bf038cKenny Root 865655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root 870655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 871655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.erase(it); 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 928a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 934a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 940a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (userState == NULL) { 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 957655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 960a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 961a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 962a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 963a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 964a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 965655b958eb2180c7c06889f83f606d23421bf038cKenny Root 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(filename, sizeof(filename), "%u_", uid); 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root 969a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 977655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(file->d_name, filename, n)) { 981a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 982a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 983a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 984a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 985a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 986a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 987a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 988a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 989655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 990655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 991655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 992655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 993a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 994a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 995655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 996655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 997f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 998f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 999822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1000822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1001822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1002822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1003822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 100407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1005cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1006cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1007cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1008cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1009655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 1011f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1012f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1013cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1014cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1015cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1016822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1017822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 101817208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 101917208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 102017208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 102117208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 102217208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 102317208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 102417208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 102517208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 102617208e0de5a42722901d803118745cca25fd10c1Kenny Root uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 102717208e0de5a42722901d803118745cca25fd10c1Kenny Root 102817208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 102917208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 103017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 103117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid); 103217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 103317208e0de5a42722901d803118745cca25fd10c1Kenny Root } 103417208e0de5a42722901d803118745cca25fd10c1Kenny Root 1035d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1036822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1037822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1038822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1039822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1040822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1041a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1045f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1046f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1047a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1048a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 104907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1052655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 105307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1054a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 105670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 105770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 105870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 105907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1060655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1061655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1062655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1063655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1064655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1065655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1066655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1067655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 106870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 106970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 107070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1072a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1073a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 107470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1076f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1077f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1078822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1079822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1080822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1081822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1082822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1083822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1084822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1085822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1086822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 108717208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 108807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1089822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 109017208e0de5a42722901d803118745cca25fd10c1Kenny Root // If this is an old device HAL, try to fall back to an old version 109117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (mDevice->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_2) { 109217208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength); 109317208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 109417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 109517208e0de5a42722901d803118745cca25fd10c1Kenny Root 109617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 109717208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 109817208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 109917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1105f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 110617208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1107f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1108655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1109822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1110822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 11111b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 11121b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 11131b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 11141b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 11151b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11161b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 11171b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 11181b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 11191b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 11201b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 11211b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 11221b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 11231b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11248ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 11258ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 112886b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 1129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1130655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1131655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1132655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1133655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1134a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1135655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1136655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1137655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 113886b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 1139655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1140655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1141655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1142655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1143655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 114470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1145655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 114686b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1147655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 114886b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1149655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1150655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1151655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 115286b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(), 115386b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1154655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1155655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1158655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1159655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1162655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1163655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1164655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1165655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1166655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1167655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1168655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1169655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1170655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1171655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1172655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1173655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1175655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1176655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1177655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1178655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1179655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1180655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1181655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1182655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1183a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1184655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1185655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1187a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1188655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1189655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1190655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1191655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1192655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1193655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1194655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1195655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1196655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1197655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1198655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1199655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1200655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1201a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1202655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1203a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1204a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1205655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1206655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1207655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 12081b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1209655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 121007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1211655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1213655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1215655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 121670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1217655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 122070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1221655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1222655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1223655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1224655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1225655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1226655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 122770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1228655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 122970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 123070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 123370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1235822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1236822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1237822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1238822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1239655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1240655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1241822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1242822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1243822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1244822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1245822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1246822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1247822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1248822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1249822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1250655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1251822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1252822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1253822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1254822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1255822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1256f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1257f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1258f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1259f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1260f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1261f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1262f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1263f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1264f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1268cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1269822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1270822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1271822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1272822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1273cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1274cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1275822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1276822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1277822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1278822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1279822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1280822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1281822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1282822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1283655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1284822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1285822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1286822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1287822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1288822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1289822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1298822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1299822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1301822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1302822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1303822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 130470c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 130570c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1309822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1310822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1311f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1312f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1313822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1314822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1315822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1316822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1317655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1318822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 131970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1320655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1321655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1322655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1323655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1324655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1325655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1326655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1327655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1328655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1329655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1330655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 133170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 133270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1333655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1334655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1336655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1337655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1338655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1339655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1340655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1341655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1342655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1343655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1344655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 134570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1346655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1347655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 134870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 134970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1350655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1355655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1359655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1360655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1364655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1366655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1368655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1370655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1372655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1373655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1374655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1376655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1385655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1387655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1391655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1392655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1409655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1415655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1417655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1418655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 141970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1420655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 142170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1422655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1423655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 142470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14251b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 14261b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 142807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 142907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 143007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 143107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 143207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 143307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 143507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 143707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 143907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1440d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1441d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 1442d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 144307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 144407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1446655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 144907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1450d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1451d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1452d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 145307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 145407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 145607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 145707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1458494689083467ec372a58f094f041c8f102f39393Kenny Root 1459655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1460494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 146107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1462655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 146407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 146507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 146607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 146807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 146907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 147007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 147107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 147207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1475f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1476f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1477d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1478d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1479d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 148007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 148107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 148207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1483f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1484f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1485f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1486f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1487f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1488f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1489494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1490494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1491494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1492b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1493b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1494b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1496655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 149707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 149807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1499ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1500ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 1501655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 1502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1504494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1505d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1506d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1507d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 150807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1511494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1512494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1513494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1514b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1515b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1516b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1518655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1519298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 152007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1521655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1522655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 152407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 152507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1527298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1528298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1529494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1530d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1531d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1532d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 153507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1536494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1537494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1538494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1539b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1540b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1541b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1543655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1545655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 154607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1549298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1550298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1551494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1552d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1553d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1554d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 155507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 155607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1558494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1559494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1560494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1561b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1562b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1563b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1564655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1565655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 156807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 157007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1572655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 157407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1578655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1579655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1581655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1582655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1583655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1584655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1585655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1586655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1587655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 159207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 159507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 159607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 159707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 159807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 160307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 160407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1605298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1606298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 160707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1608d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1609d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1610d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 161107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 161207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1614655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 161607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 161707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 162207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 162407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 163107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 163507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 163807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 163907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 164207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1643d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1644d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1645d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 164607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 164707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 165207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 165307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1654655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 165507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 165707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1658655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 165907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 166107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1662655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 166607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 166807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1669d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1670d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1671d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 167207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 167307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 167407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1675655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16769d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 167707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 167807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 168070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1681655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 168207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 168370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1686d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1687d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1688d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1692655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16939d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 169707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 169907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 170070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 170170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1703d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1704d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1705d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 170607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 170707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 170870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1709655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 171070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 171170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 171296427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 171396427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1714d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1715d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1716d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 171707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1720494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1721494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1722494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1723b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1724b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1725b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1726655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1727f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1728f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 172907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 173007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 173307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 173407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 173517208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 173670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 173807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 173907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 174007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 174207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 174307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 174407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 174617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 174796427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 174896427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 174996427baf0094d50047049d329b0779c3c910402cKenny Root 175096427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 175196427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 175296427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 175396427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 175496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 175596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 175696427baf0094d50047049d329b0779c3c910402cKenny Root } 175796427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 175896427baf0094d50047049d329b0779c3c910402cKenny Root 175996427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 176096427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 176196427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 176296427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 176396427baf0094d50047049d329b0779c3c910402cKenny Root 176496427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 176596427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 176696427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 176796427baf0094d50047049d329b0779c3c910402cKenny Root 176896427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 176996427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 177096427baf0094d50047049d329b0779c3c910402cKenny Root 177196427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 177296427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 177396427baf0094d50047049d329b0779c3c910402cKenny Root } else { 177496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 177596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 177696427baf0094d50047049d329b0779c3c910402cKenny Root } 177796427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 177896427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 177996427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 178096427baf0094d50047049d329b0779c3c910402cKenny Root } 178196427baf0094d50047049d329b0779c3c910402cKenny Root 178217208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) { 178317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 178417208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 178517208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 178617208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 178717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 178817208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 178996427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 179096427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 179196427baf0094d50047049d329b0779c3c910402cKenny Root 179296427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 179396427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 179496427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 179596427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 179696427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 179796427baf0094d50047049d329b0779c3c910402cKenny Root } 179896427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 179996427baf0094d50047049d329b0779c3c910402cKenny Root 180017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) { 180117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 180217208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 180317208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 180417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 180517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 180696427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 180796427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 180896427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 180996427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 181096427baf0094d50047049d329b0779c3c910402cKenny Root 181196427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 181296427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 181396427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 181496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 181596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 181696427baf0094d50047049d329b0779c3c910402cKenny Root } 181796427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 181896427baf0094d50047049d329b0779c3c910402cKenny Root 181996427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 182096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid number of arguments: %d", args->size()); 182196427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 182296427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 182396427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 182496427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 182596427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 182696427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 182796427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 182896427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 182996427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 183096427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 183196427baf0094d50047049d329b0779c3c910402cKenny Root } 183296427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 183396427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 183496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 183596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 183696427baf0094d50047049d329b0779c3c910402cKenny Root } 183796427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 183896427baf0094d50047049d329b0779c3c910402cKenny Root } 183996427baf0094d50047049d329b0779c3c910402cKenny Root } 184096427baf0094d50047049d329b0779c3c910402cKenny Root 184196427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 184296427baf0094d50047049d329b0779c3c910402cKenny Root } else { 184396427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 184496427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 184596427baf0094d50047049d329b0779c3c910402cKenny Root } 184670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 184707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 184807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 184907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 185070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1851655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1852655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 185370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 185407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 185507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 185607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1857ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 185817208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 185917208e0de5a42722901d803118745cca25fd10c1Kenny Root 1860655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 186170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 186270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1863f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1864f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1865d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1866d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1867d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 186807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 186907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 187070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1871494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1872494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1873494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1874b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1875b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1876b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1877655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1878f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 187907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 188007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 188107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 188270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 188460898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 188570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1886f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mKeyStore->importKey(data, length, filename.string(), callingUid, flags); 188770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 188870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 189007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1891d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1892d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1893d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 189407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 189507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18969a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 189707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 189807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 189970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1900d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 190107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 190270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1903655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1904d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 190507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 190607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 190707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 190907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 191007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 191107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 191207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 191307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 191507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 191607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 191707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 191807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 192007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 192107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 192207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 192307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 192417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 192517208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 192617208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 192717208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 192817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 192917208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 193017208e0de5a42722901d803118745cca25fd10c1Kenny Root } 193107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 193207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 193307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 193407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 193570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 193607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 193770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 193870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 193907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 194007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1941d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1942d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1943d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 194407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 194507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1947655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 19489d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 194907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 195007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 195107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 195270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 195307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 195407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 195507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 195670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1957655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1958494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 195907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 196007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 196107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 196307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 196407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 196507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 196607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 196807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 196907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 197007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 197107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 197207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 197307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 197407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 197570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 197617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 197717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 197817208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 197917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 198017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 198117208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 198217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 198307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 198407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 198507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 198707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 198970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 199007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 199107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 199207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 199407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 199507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 199607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 199707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 199807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 199907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 200007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 200107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 2002d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2003d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 2004d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 200507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 200607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 200907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 201070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2011d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 201270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2013655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 201407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 201607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 201707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 202007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 202107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 202207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 202370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 202407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 202507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 202607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 202707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2028344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 202917208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 203017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 203117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 203217208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 203317208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 203417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 203517208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 203617208e0de5a42722901d803118745cca25fd10c1Kenny Root } 203707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 203807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 203907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2040344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 204107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2042344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2043344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2044494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2045d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2046d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 2047d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 204807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 204907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2050344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2051494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2052494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2053494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2054b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2055b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2056b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2058655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 2059344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 2061655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 2062655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2066a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 2068a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 207007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 207417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 207707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2080a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 208207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 208307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2084a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 208507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 2086a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2089d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2090d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 2091d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 209207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2095655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20969d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 209707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2102655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2104655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 210607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2108655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 210907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2110a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 211107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2113d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2114d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 2115d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 211607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 211707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2119655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21209d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 212407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 212507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2126655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2128655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 212907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 213007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 213107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2132655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2133a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2136d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2137d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 2138d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 213936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 214007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 214107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 214207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2143655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2145655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2146655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 214736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2148a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 214907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2150655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 215107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2152655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 215336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 215607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 215707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 215807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 215907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2160655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 216136a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 216307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 216436a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 216607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2167d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2168d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 21690225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2170d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!has_permission(callingUid, P_DUPLICATE)) { 2171d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 21720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 21730225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21740225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2175655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21760225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2177d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 21780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 21790225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21800225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2181d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2182d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2183d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2184d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 21850225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 21860225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21870225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2188d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2189d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2190d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21910225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2192d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2193d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2194d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2195d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2196d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2197d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21980225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2199d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2200d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2201d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2202d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22030225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22040225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2205d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2206655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2207d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2208d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2209655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, srcUid)); 22100225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2211655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2212655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 22130225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 22140225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22150225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2216d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2217655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2218655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 2219d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2220d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 22210225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2222d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2223655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, callingUid); 22240225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22250225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 22261b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 22271b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 22288ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 22298ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2230a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root int32_t clear_uid(int64_t targetUid) { 2231a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2232a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!has_permission(callingUid, P_CLEAR_UID)) { 2233a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2234a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2235a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2236a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2237655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 2238a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!isKeystoreUnlocked(state)) { 2239a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGD("calling clear_uid in state: %d", state); 2240a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return state; 2241a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2242a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2243a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2244a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2245655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2246a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2247a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2248a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2249655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(callingUid); 2250655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2251a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2252655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2253a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2254a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2255a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2256655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2257655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", static_cast<uid_t>(targetUid)); 2258a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2259a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2260a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2261a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2262a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2263655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2264655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2265a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2266a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2267a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2268655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2269655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2270655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2271655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2272655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2273655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2274655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2275655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2276a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2277655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2278a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2279655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, callingUid) 2280655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2281655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2282a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2283a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2284a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2285a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2286a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 228717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 2288a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2289a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2290655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2291a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2292a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2293a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2294a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 22955f53124250025d3113c9c598a2f101330144b10cKenny Root if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) { 2296a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2297655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2298a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2299a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2300a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2301a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2302a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2303a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2304a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 230507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 23069d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 23079d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 23089d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 23099d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 23109d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 23119d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 23129d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 23139d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 23149d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 231607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 231707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 231807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 231907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 232007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 233670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 233770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 233870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 233970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 234070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 234170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 234270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 234370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2344655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 234507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 234607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 234707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 234807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 234907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 235007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 235270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 235307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 235407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 235507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 235607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 235707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 235870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 235907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2362