keystore.cpp revision 655b958eb2180c7c06889f83f606d23421bf038c
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 45655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h> 46822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <utils/UniquePtr.h> 47655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h> 4870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 5007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 63a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 64a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 65a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 66a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 68a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 69822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 70822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 71822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 72822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 73822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 74822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 75822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 77822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 78822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 79822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 81822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 82822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 9270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 9370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 9470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 9570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 9670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 9770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 9870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 9970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 10370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 12107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 12207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 12307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 12407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 12507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 126d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_TEST = 1 << 0, 127d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GET = 1 << 1, 128d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_INSERT = 1 << 2, 129d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DELETE = 1 << 3, 130d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_EXIST = 1 << 4, 131d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SAW = 1 << 5, 132d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_RESET = 1 << 6, 133d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_PASSWORD = 1 << 7, 134d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_LOCK = 1 << 8, 135d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_UNLOCK = 1 << 9, 136d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_ZERO = 1 << 10, 137d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SIGN = 1 << 11, 138d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_VERIFY = 1 << 12, 139d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GRANT = 1 << 13, 140d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DUPLICATE = 1 << 14, 141a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root P_CLEAR_UID = 1 << 15, 14207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 14307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 14407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 14507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 14607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 14707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 14807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 14907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 15007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 15107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 15207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 15507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 15607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 15707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 15807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 166655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 167655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 168655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 169655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 170655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 171655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 172655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 173655b958eb2180c7c06889f83f606d23421bf038cKenny Root 174655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 175655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 176655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 177655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 178655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 179655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 180655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 181655b958eb2180c7c06889f83f606d23421bf038cKenny Root 182655b958eb2180c7c06889f83f606d23421bf038cKenny Root 18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic bool has_permission(uid_t uid, perm_t perm) { 184655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 185655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 186655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 187655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 188655b958eb2180c7c06889f83f606d23421bf038cKenny Root 18907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 19007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 19107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 19207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.perms & perm; 19307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 19407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 19507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 19607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return DEFAULT_PERMS & perm; 19707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 19807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 199494689083467ec372a58f094f041c8f102f39393Kenny Root/** 200494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 201494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 202494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 203494689083467ec372a58f094f041c8f102f39393Kenny Root */ 20407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 20507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 20607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 20707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 20807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 20907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 21007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 21107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 21207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 215494689083467ec372a58f094f041c8f102f39393Kenny Root/** 216494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 217494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 218494689083467ec372a58f094f041c8f102f39393Kenny Root */ 219494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 220494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 221494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 222494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 223494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 224494689083467ec372a58f094f041c8f102f39393Kenny Root } 225494689083467ec372a58f094f041c8f102f39393Kenny Root } 226494689083467ec372a58f094f041c8f102f39393Kenny Root 227494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 228494689083467ec372a58f094f041c8f102f39393Kenny Root} 229494689083467ec372a58f094f041c8f102f39393Kenny Root 230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 237655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 238655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 239655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 240655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 241655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 242655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 243655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 244655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 245655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 246655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 247655b958eb2180c7c06889f83f606d23421bf038cKenny Root 24807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 24907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 25007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 251a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 252655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 253a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 254a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 255a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 256655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 257655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 258a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 259a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 260a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 26170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 26270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 26370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 26407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) { 26570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 26670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 26770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 26807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return n + encode_key(out, keyName); 269a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 270a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 27107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 27207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 27307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 27407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 27507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 27607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 27707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 27807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 27907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 28007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 28107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 28707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 29007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 29207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 29307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 29407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 29507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 29607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 29707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 29907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 30007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 30207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 311150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 3125281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 313150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 324150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 325150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 326150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 327150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 339150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 346150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 347150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3545187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 366822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 367822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other 368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 371822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 372822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 373822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 374822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 375822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 376822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 377822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 378822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 379822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 380822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 381822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 382822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 383822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 384822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 386822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 387822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 388822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t reserved; 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 391822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 393822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 398822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 399d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 400822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 401822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 402822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 403822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 404822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 40507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 1; 406822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 40907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 41007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 416822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 41707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 418822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4275187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4315187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4355187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4365187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4375187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4385187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4395187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 443822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 444822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 445822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 446822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 447822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 448822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 449822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 450822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 452822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 454822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) { 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 461150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read random data for: %s", filename); 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 471a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root aes_key, vector, AES_ENCRYPT); 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.reserved = 0; 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 490150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 491150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 492150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 493150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 501150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 505150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 506150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 507150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 508150ca934edb745de3666a6492b039900df228ff0Kenny Root } 509150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) { 513150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 514150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) { 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.vector, AES_DECRYPT); 535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, computedDigest); 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 55107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 555a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 556a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 558655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 559655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 560655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 561655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 562655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 563655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 56470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 565655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 566655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 567655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 568655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 56970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 570655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 571655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 572655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 573655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 574655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 575655b958eb2180c7c06889f83f606d23421bf038cKenny Root 576655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 58170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 582655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 583655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 584655b958eb2180c7c06889f83f606d23421bf038cKenny Root 585655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 586655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 587655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 588655b958eb2180c7c06889f83f606d23421bf038cKenny Root 589655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 590655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 591655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 592655b958eb2180c7c06889f83f606d23421bf038cKenny Root 593655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 594655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 595655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 596655b958eb2180c7c06889f83f606d23421bf038cKenny Root 597655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 598655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 599655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 600655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 601655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6045187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6085187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 612655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 613655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 614655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 615655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 616655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 61770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 61870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 619655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 620655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 623655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 62807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 631655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 636822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 637655b958eb2180c7c06889f83f606d23421bf038cKenny Root return masterKeyBlob.encryptBlob(mMasterKeyFile, &passwordAesKey, entropy); 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 640655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 641655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 642150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 665655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = masterKeyBlob.decryptBlob(mMasterKeyFile, &passwordAesKey); 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 672655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 675655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 697655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 698655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 699655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 701655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 702655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 703655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 705655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 706655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 708655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 711655b958eb2180c7c06889f83f606d23421bf038cKenny Root 712655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 714655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 715655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 716655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 717655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 718655b958eb2180c7c06889f83f606d23421bf038cKenny Root 719655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 720655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 721655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 722655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 723655b958eb2180c7c06889f83f606d23421bf038cKenny Root 724655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's UID. 725655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 726655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 727655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 728655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 729655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 730655b958eb2180c7c06889f83f606d23421bf038cKenny Root 731655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip if this is not our user. 732655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_user_id(thisUid) != mUserId) { 733655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 734655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 735655b958eb2180c7c06889f83f606d23421bf038cKenny Root 736655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 742655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 743655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 744655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 745655b958eb2180c7c06889f83f606d23421bf038cKenny Root 746655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 748655b958eb2180c7c06889f83f606d23421bf038cKenny Root 749655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 750655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 751655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 752655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 753655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 754655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 755655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 756655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 757655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 758655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 759655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 760655b958eb2180c7c06889f83f606d23421bf038cKenny Root 761655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 762655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 763655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root 765655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 767655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 768655b958eb2180c7c06889f83f606d23421bf038cKenny Root 769655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 770655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 771655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 772655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 774655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 775655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 776655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 777655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 778655b958eb2180c7c06889f83f606d23421bf038cKenny Root 779655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 780655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 781655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 782655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 783655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 784655b958eb2180c7c06889f83f606d23421bf038cKenny Root 785655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 786655b958eb2180c7c06889f83f606d23421bf038cKenny Root 787655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 788655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 789655b958eb2180c7c06889f83f606d23421bf038cKenny Root 790655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 791655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 792655b958eb2180c7c06889f83f606d23421bf038cKenny Root 793655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 794655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 795655b958eb2180c7c06889f83f606d23421bf038cKenny Root 796655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 797655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 798655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 799655b958eb2180c7c06889f83f606d23421bf038cKenny Root 800655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 801655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 802655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 803655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 804655b958eb2180c7c06889f83f606d23421bf038cKenny Root 805655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 806655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 807655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 808655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 809655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 810655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 811655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 812655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 813655b958eb2180c7c06889f83f606d23421bf038cKenny Root 814655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 815655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 816655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 817655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 818655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 819655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 820655b958eb2180c7c06889f83f606d23421bf038cKenny Root 821655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 822655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 823655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 824655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.erase(it); 825655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 826655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 827655b958eb2180c7c06889f83f606d23421bf038cKenny Root 828655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 829655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 830655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 831655b958eb2180c7c06889f83f606d23421bf038cKenny Root 832655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 834655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 835655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 836655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 837655b958eb2180c7c06889f83f606d23421bf038cKenny Root 838655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 839655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 840655b958eb2180c7c06889f83f606d23421bf038cKenny Root 841655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 843655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 844655b958eb2180c7c06889f83f606d23421bf038cKenny Root 845655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 846655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 847655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 848655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root 850655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 851655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 852655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 854655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root 856655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 859655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 861655b958eb2180c7c06889f83f606d23421bf038cKenny Root 862655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 863655b958eb2180c7c06889f83f606d23421bf038cKenny Root char encoded[encode_key_length(keyName)]; 864655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 865655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root char encoded[encode_key_length(keyName)]; 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root char encoded[encode_key_length(keyName)]; 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (userState == NULL) { 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 895a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 896a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 897a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 898a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 899a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(filename, sizeof(filename), "%u_", uid); 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root 904a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(file->d_name, filename, n)) { 916a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 917a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 918a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 919a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 920a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 921a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 922a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 923a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 928a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 929a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = keyBlob->decryptBlob(filename, userState->getDecryptionKey()); 933822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 934822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 935822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 936822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 937822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 93807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 939cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 940cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 941cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 942cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root || (rc = keyBlob->decryptBlob(filename, userState->getDecryptionKey())) 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root != NO_ERROR) { 947cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 948cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 949cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 950822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 951822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 952d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 953822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 954822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 955822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 956822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 957822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 958a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 959a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root return keyBlob->encryptBlob(filename, userState->getEncryptionKey(), mEntropy); 963a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 964a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 96507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 96907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 970a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 97270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 97370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 97470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 97507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 977655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 983655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 98470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 98570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 98670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 98770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 988a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 989a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 99070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 99170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 992655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid) { 993822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 994822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 995822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 996822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 997822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 998822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 999822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1000822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1001822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 100207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1003822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 1004822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 1005822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1006822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1007822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1008822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1009822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1010822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1012822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1013822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 10148ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root bool isHardwareBacked() const { 1015483407eaca108d3717bb49770915d6d95d5d0e0cKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 10168ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 10178ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1018655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1019655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 1020655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 1021655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key_for_uid(filename, uid, keyName); 1022a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1023655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1024655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 filepath8; 1025a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (filepath8.string() == NULL) { 1028655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't create filepath for key %s", filename); 1029655b958eb2180c7c06889f83f606d23421bf038cKenny Root return SYSTEM_ERROR; 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1031a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1032655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1033655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1034655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1035655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1036a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1037655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1038655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1039655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 1040655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key_for_uid(filename, euid, keyName); 1041655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1042655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1045655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1046655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 104770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1048655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 1049655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(filename, keyName); 1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root strtoul(filename, &end, 10); 1052655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1053655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1054655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1056655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1057655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1058a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1059a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1060655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1061655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1062a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1063a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1064655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1065655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1066655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1067655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1068655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1069655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1070655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1071655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1072655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1073655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1074655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1075655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1076a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1077655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1078655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1079655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1080655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1081655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1082655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1083655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1084655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1085a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1086655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1087655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1088a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1089a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1090655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1091655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1092655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1093655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1094655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1095655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1096655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1097655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1098655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1099655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1100655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1101655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1102655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1103a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1104655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1105a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1106a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1107655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1108655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1109655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 1110655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 111107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1112655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1113a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1114655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1115655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1116655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 111770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1118655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1119655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1120655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 112170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1124655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1125655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 112870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1129655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 113070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 113170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 113470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1136822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1137822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1138822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1139822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1140655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1141655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1142822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1143822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1144822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1145822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1146822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1147822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1148822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1149822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1150822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1151655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1152822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1153822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1154822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1155822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1156822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1157822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1158822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1159822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1160cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1161822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1162822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1163822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1164822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1165cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1166cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1167822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1168822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1169822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1170822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1171822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1172822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1173822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1174822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1175655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1176822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1177822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1178822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1179822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1180822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1181822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1182822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1183822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1184822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1185822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1186822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1187822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1188822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1189822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1190822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1191822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1192822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1193822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1194822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1195822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 119670c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 119770c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1198822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1199822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1200822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1201822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1202822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1203655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid); 1204822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1205822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1206822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1207822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1208655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1209822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 121070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1211655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1212655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1213655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1215655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1216655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1217655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1220655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1221655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 122270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 122370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1224655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1225655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1226655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1227655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1228655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1229655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1230655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1231655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1232655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1233655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1234655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1235655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 123670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1237655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1238655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 123970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 124070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1241655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1242655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1243655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1244655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1245655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1246655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1247655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1248655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1249655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1250655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1251655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1252655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1253655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1254655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1255655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1256655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1257655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1258655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1259655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1260655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1261655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1262655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1263655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1264655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1265655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1266655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1267655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1268655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1269655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1270655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1271655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1272655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1273655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1274655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1275655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1276655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1277655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1278655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1279655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1280655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1281655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1282655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1283655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1284655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1285655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1286655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1287655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1288655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1289655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1290655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1291655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1292655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1293655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1294655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1295655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1296655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1297655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1298655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1299655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1300655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1301655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1302655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1303655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1304655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1305655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1306655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1307655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1308655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1309655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 131070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1311655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 131270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1313655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1314655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 131570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 131607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 131707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 131807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 131907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 132007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 132107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 132207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 132407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 132507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 132607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 132807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1329d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1330d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 1331d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 133207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 133307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 133807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1339d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1340d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1341d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 134207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 134307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1345655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 13469d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 134707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get in state: %d", state); 134807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 134907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 135107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 135207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1353494689083467ec372a58f094f041c8f102f39393Kenny Root 1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1355494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 135607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 135807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 135907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 136007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 136107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 136207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 136307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 136407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 136507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 136607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 136707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1370494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid) { 1371d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1372d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1373d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 137407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 137507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 137607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1377494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1378494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1379494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1380b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1381b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1382b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 13849d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 138507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling insert in state: %d", state); 138607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 1387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 138807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 138907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 139107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 139207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 1394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1396494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1397d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1398d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1399d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 140007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 140107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 140207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1403494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1404494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1405494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1406b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1407b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1408b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 140907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1411298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 141207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 141507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 141607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 141707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 141807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1419298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1420298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1421494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1422d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1423d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1424d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 142507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 142607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1428494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1429494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1430494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1431b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1432b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1433b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 143407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1435655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1437655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 143807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 143907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 144007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1441298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1442298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1443494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1444d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1445d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1446d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 144707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 144807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 144907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1450494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1451494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1452494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1453b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1454b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1455b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1456655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1457655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 145807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1459655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 146007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 146107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 146207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1464655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1465655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 146607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 146807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1469655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1470655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1471655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1472655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1473655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1474655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1475655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1476655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1477655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1478655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1479655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 148007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 148107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 148207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 148307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 148407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 148507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 148607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 148707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 148807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 148907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 149007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 149607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1497298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1498298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 149907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1500d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1501d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1502d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 150307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1506655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 150807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 150907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 151107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 151507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 151607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 151907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 152007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 152107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 152707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 152807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 153007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 153107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 153207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1535d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1536d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1537d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1543655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1546655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1550655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 155107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 155307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1554655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 155507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 155807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1561d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1562d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1563d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 15689d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 157007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 157107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 157270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 157407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 157570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 157707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1578d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1579d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1580d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 158107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1584655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 15859d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 159270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 159370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1595d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1596d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1597d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 159807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1601655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 160270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 160370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1604494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t generate(const String16& name, int targetUid) { 1605d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1606d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1607d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 160807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 160907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 161070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1611494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1612494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1613494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1614b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1615b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1616b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1617655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16189d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling generate in state: %d", state); 162007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 162270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 162407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 162507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 162670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 163170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 163307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 163407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 163570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_keygen_params_t rsa_params; 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.modulus_size = 2048; 163807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.public_exponent = 0x10001; 163970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 164207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 164307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 164470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1645655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1646655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 164770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 164807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 165007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 165270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 165370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1654494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid) { 1655d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1656d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1657d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 165807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 165907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1661494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1662494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1663494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1664b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1665b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1666b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1667655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16689d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 166907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 167007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 167107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 167270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 167307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1674655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 167570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1676655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->importKey(data, length, filename.string(), callingUid); 167770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 167870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 168007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1681d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1682d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1683d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 16869a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 1687655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16889d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling sign in state: %d", state); 169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 16919a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } 169270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 169570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1696d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 169707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 169870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1699655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1700d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 170470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 170507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 170607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 170707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 170807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 170907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 171107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 171307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 171407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 171607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 171707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 171807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 171907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 172007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 172107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, length, out, outLength); 172207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 172307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 172507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 172870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 172970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 173107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1732d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1733d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1734d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 173507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1738655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17399d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 174007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 174107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 174207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 174407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 174507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 174607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 174770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1748655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1749494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 175007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 175107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 175207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 175370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 175507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 175607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 175707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 175870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 176007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 176107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 176307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 176407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 176507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 176670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 176707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, dataLength, signature, signatureLength); 176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 177007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 177107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 177207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 177307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 177470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 177570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 177607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 177907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 178007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 178107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 178207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 178307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 178407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 178507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 178607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 178707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 1788d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1789d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1790d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 179107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 179207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1794655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17959d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 179607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get_pubkey in state: %d", state); 179707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 179807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 180107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 180270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1803d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 180470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1805655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 180607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 180707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 180807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 180907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 181107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 181207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 181307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 181407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 181607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 181707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 181807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 181907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1820344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 182107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 182207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root pubkeyLength); 182307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 182407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 182507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1826344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 182707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1828344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1829344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1830494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 1831d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1832d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1833d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 183407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 183507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1836344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1837494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1838494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1839494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1840b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1841b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1842b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 184307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1844655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 1845344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 184607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1847655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 1848655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 184907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 185007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 185107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 185307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 1854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 185507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 185607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 185707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 185807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 185907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 186007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair != NULL) { 186107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 186207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 186307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 186707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 186807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 186907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 187107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1872a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 187307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 187407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 1875d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1876d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1877d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 187807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 187907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 188007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1881655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 18829d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 188307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 188407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 188507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 188607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 188707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1888655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 188907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1890655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 189107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 189207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 189307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1894655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 189507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1896a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 189707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 189807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 1899d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1900d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1901d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 190207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 190307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1905655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 19069d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 190707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 190807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 190907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 191107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1912655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 191307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1914655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 191507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 191607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1918655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 1919a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 192007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 192107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 1922d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1923d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1924d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 192536a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 192607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 192707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 192807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1929655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 193007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1931655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 1932655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 193336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 1934a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 193507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1936655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 193707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 1938655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 193936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 194007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 194207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 194307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 194407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 194507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 1946655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 194736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 194807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 195036a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 1951a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 195207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1953d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 1954d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 19550225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1956d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!has_permission(callingUid, P_DUPLICATE)) { 1957d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 19580225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 19590225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 19600225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1961655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 19620225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 1963d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 19640225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 19650225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 19660225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1967d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 1968d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 1969d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 1970d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 19710225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 19720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 19730225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1974d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 1975d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 1976d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 19770225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1978d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 1979d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 1980d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 1981d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 1982d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 1983d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 19840225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1985d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 1986d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 1987d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 1988d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 19890225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 19900225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1991d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 1992655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 1993d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 1994d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 1995655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, srcUid)); 19960225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1997655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 1998655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 19990225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 20000225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20010225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2002d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2003655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2004655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 2005d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2006d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 20070225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2008d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2009655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, callingUid); 20100225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20110225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 20128ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root int32_t is_hardware_backed() { 20138ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root return mKeyStore->isHardwareBacked() ? 1 : 0; 20148ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 20158ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2016a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root int32_t clear_uid(int64_t targetUid) { 2017a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2018a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!has_permission(callingUid, P_CLEAR_UID)) { 2019a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2020a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2021a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2022a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2023655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 2024a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!isKeystoreUnlocked(state)) { 2025a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGD("calling clear_uid in state: %d", state); 2026a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return state; 2027a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2028a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2029a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2030a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2031655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2032a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2033a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2034a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2035655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(callingUid); 2036655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2037a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2038655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2039a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2040a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2041a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2042655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2043655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", static_cast<uid_t>(targetUid)); 2044a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2045a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2046a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2047a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2048a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2049655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2050655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2051a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2052a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2053a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2054655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2055655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2056655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2057655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2058655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2059655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2060655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2061655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2062a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2063655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2064a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2065655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, callingUid) 2066655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2067655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2068a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2069a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2070a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2071a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2072a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 2073a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair != NULL) { 2074a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2075a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2076655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2077a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2078a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2079a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2080a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2081655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (unlinkat(dirfd(dir), filename.string(), 0) && errno != ENOENT) { 2082a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2083655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2084a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2085a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2086a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2087a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2088a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2089a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2090a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 209107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 20929d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 20939d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 20949d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 20959d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 20969d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 20979d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 20989d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 20999d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 21009d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2101a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 210407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2107a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2108a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2109a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2110a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2111a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2112a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2113a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2114a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2115a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2116a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2117a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2118a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2119a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2120a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2121a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 212270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 212370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 212470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 212570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 212670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 212770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 212870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 212970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2130655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 213107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 213207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 213307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 213607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2137a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 213870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 213907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 214007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 214107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 214207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 214307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 214470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 214507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2146a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2147a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2148