keystore.cpp revision f9119d6414f43ef669d64e9e53feb043eda49cf3
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, 367f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. 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; 388f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 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 405f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 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); 419f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 420f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4295187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4335187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4375187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4385187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4395187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4405187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4415187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 445822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 446822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 447822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 448822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 449f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 450f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 451f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 452f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 453f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 454f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 455f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 456f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 457f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 458f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 459f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 460f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 461f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 462f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 463f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 464f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 465822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 477f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 478f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 479f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 480f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 481f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 482f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 483f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 484f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 485f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 486f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 487f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 488f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 505f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 506f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 507f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 508f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 509f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 510f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 511f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 512f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 518150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 519150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 520150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 521150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 529150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 533150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 534150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 535150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 536150ca934edb745de3666a6492b039900df228ff0Kenny Root } 537150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 540f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 541f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 542150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 543150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 553f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 554f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 555f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 556f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 557f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 564f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 567f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 568f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 569f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 570f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 571f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 572f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 573f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 574f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 575f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 576f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 577f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 578f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 579f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 580f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 581f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 582f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 583f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 59507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 602655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 603655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 604655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 605655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 606655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 607655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 60870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 609655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 610655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 611655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 612655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 61370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 614655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 615655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 616655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 617655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 618655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 619655b958eb2180c7c06889f83f606d23421bf038cKenny Root 620655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 62570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 626655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 627655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 628655b958eb2180c7c06889f83f606d23421bf038cKenny Root 629655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 630655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 631655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 632655b958eb2180c7c06889f83f606d23421bf038cKenny Root 633655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 634655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 635655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 636655b958eb2180c7c06889f83f606d23421bf038cKenny Root 637655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 638655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 639655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 640655b958eb2180c7c06889f83f606d23421bf038cKenny Root 641655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 642655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 643655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 644655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 645655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6485187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6525187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 656655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 657655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 658655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 659655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 660655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 66170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 66270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 663655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 664655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 667655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 67207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 675655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 680822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 681f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 684655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 685655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 686150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 709f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 710f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 712f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 717655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 720655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 732a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 742655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 743655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 744655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 746655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 748655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 750655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 751655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 753655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 756655b958eb2180c7c06889f83f606d23421bf038cKenny Root 757655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 759655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 760655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 761655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 762655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 763655b958eb2180c7c06889f83f606d23421bf038cKenny Root 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 765655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 767655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 768655b958eb2180c7c06889f83f606d23421bf038cKenny Root 769655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's UID. 770655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 771655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 772655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 774655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 775655b958eb2180c7c06889f83f606d23421bf038cKenny Root 776655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip if this is not our user. 777655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_user_id(thisUid) != mUserId) { 778655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 779655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 780655b958eb2180c7c06889f83f606d23421bf038cKenny Root 781655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 787655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 788655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 789655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 790655b958eb2180c7c06889f83f606d23421bf038cKenny Root 791655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 792655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 793655b958eb2180c7c06889f83f606d23421bf038cKenny Root 794655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 795655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 796655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 797655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 798655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 799655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 800655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 801655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 802655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 803655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 804655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 805655b958eb2180c7c06889f83f606d23421bf038cKenny Root 806655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 807655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 808655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 809655b958eb2180c7c06889f83f606d23421bf038cKenny Root 810655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 811655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 812655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 813655b958eb2180c7c06889f83f606d23421bf038cKenny Root 814655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 815655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 816655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 817655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 818655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 819655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 820655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 821655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 822655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 823655b958eb2180c7c06889f83f606d23421bf038cKenny Root 824655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 825655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 826655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 827655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 828655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 829655b958eb2180c7c06889f83f606d23421bf038cKenny Root 830655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 831655b958eb2180c7c06889f83f606d23421bf038cKenny Root 832655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 834655b958eb2180c7c06889f83f606d23421bf038cKenny Root 835655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 836655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 837655b958eb2180c7c06889f83f606d23421bf038cKenny Root 838655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 839655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 840655b958eb2180c7c06889f83f606d23421bf038cKenny Root 841655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 843655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 844655b958eb2180c7c06889f83f606d23421bf038cKenny Root 845655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 846655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 847655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 848655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root 850655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 851655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 852655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 854655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 856655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root 859655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 861655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 862655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 863655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 864655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 865655b958eb2180c7c06889f83f606d23421bf038cKenny Root 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.erase(it); 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root char encoded[encode_key_length(keyName)]; 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root char encoded[encode_key_length(keyName)]; 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root char encoded[encode_key_length(keyName)]; 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (userState == NULL) { 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 940a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 941a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 942a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 943a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 944a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(filename, sizeof(filename), "%u_", uid); 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root 949a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 957655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(file->d_name, filename, n)) { 961a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 962a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 963a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 964a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 965a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 966a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 967a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 968a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 973a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 974a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 977f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 978f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 979822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 980822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 981822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 982822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 983822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 98407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 985cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 986cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 987cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 988cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 989655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 990655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 991f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 992f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 993cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 994cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 995cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 996822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 997822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 998d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 999822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1000822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1001822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1002822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1003822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1004a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1005a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1008f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1009f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1010a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1011a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 101207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1014655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1015655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 101607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1017a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1018655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 101970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 102070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 102170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 102207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1023655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1024655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1025655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1028655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1029655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 103170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 103270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 103370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 103470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1035a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1036a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 103770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 103870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1039f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1040f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1041822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1042822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1043822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1044822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1045822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1046822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1047822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1048822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1049822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 105007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1051822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 1052822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 1053822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1054822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1055822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1056822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1057822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1058822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1059f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1060f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1061655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1062822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1063822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 10648ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root bool isHardwareBacked() const { 1065483407eaca108d3717bb49770915d6d95d5d0e0cKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 10668ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 10678ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1068655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1069655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 1070655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 1071655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key_for_uid(filename, uid, keyName); 1072a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1073655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1074655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 filepath8; 1075a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1076655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1077655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (filepath8.string() == NULL) { 1078655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't create filepath for key %s", filename); 1079655b958eb2180c7c06889f83f606d23421bf038cKenny Root return SYSTEM_ERROR; 1080655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1081a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1082655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1083655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1084655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1085655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1086a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1087655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1088655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1089655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 1090655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key_for_uid(filename, euid, keyName); 1091655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1092655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1093655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1094655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1095655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1096655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 109770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1098655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 1099655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(filename, keyName); 1100655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1101655b958eb2180c7c06889f83f606d23421bf038cKenny Root strtoul(filename, &end, 10); 1102655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1103655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1104655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1105655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1106655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1107655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1108a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1109a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1110655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1111655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1112a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1113a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1114655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1115655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1116655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1117655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1118655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1119655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1120655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1121655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1124655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1125655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1126a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1128655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1129655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1130655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1131655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1132655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1133655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1134655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1136655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1137655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1138a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1139a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1140655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1141655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1142655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1143655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1144655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1145655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1146655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1147655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1148655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1149655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1150655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1151655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1152655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1154655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1155a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1157655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1158655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1159655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 1160655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 116107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1162655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1164655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1165655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1166655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 116770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1168655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1169655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1170655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 117170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1172655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1173655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1174655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1175655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1176655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1177655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 117870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1179655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 118070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 118170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 118270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 118370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 118470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 118570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1186822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1187822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1188822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1189822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1190655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1191655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1192822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1193822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1194822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1195822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1196822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1197822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1198822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1199822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1200822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1201655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1202822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1203822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1204822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1205822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1206822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1207f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1208f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1209f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1210f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1211f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1212f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1213f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1214f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1215f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1216822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1217822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1218822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1219cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1220822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1221822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1222822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1223822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1224cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1225cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1226822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1227822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1228822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1229822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1230822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1231822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1232822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1233822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1234655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1235822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1236822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1237822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1238822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1239822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1240822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1241822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1242822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1243822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1244822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1245822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1246822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1247822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1248822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1249822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1250822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1251822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1252822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1253822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1254822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 125570c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 125670c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1257822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1258822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1259822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1260822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1261822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1262f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1263f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1264822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1268655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1269822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 127070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1271655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1272655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1273655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1274655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1275655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1276655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1277655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1278655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1279655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1280655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1281655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 128270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1284655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1285655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1286655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1287655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1288655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1289655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1290655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1291655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1292655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1293655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1294655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1295655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 129670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1297655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1298655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 129970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 130070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1301655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1302655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1303655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1304655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1305655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1306655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1307655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1308655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1309655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1310655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1311655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1312655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1313655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1314655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1315655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1316655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1317655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1318655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1319655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1320655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1321655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1322655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1323655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1324655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1325655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1326655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1327655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1328655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1329655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1330655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1331655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1332655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1333655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1334655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1336655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1337655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1338655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1339655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1340655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1341655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1342655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1343655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1344655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1345655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1346655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1347655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1348655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1349655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1350655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1355655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1359655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1360655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1364655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1366655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1368655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 137070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 137270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1373655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1374655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 137570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 137607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 137707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 137807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 137907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 138007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 138107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 138207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 138407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 138507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 138607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 138807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1389d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1390d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 1391d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 139207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 139307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 139807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1399d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1400d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1401d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 140207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 140307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 140507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 140607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1407494689083467ec372a58f094f041c8f102f39393Kenny Root 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1409494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 141007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 141207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 141307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 141407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 141507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 141607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 141707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 141807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 141907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 142007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 142107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1424f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1425f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1426d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1427d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1428d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 142907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 143007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 143107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1432f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1433f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1434f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1435f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1436f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1437f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1438494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1439494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1440494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1441b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1442b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1443b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 144407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1445655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 144607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 144707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1448655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 1449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1451494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1452d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1453d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1454d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 145507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 145607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 145707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1458494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1459494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1460494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1461b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1462b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1463b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 146407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1465655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1466298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1468655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1469655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 147007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 147107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 147207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 147307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1474298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1475298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1476494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1477d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1478d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1479d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 148007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 148107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 148207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1483494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1484494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1485494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1486b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1487b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1488b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 148907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1490655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1492655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 149307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1496298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1497298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1498494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1499d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1500d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1501d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 150207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 150407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1505494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1506494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1507494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1508b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1509b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1510b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1511655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1512655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1514655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 151507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 151607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1519655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1520655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 152107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1524655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1525655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1526655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1527655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1528655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1529655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1530655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1531655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1532655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1533655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1534655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 153507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 153607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 153707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 154607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 155007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1552298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1553298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 155407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1555d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1556d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1557d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 155807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 155907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 156807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 157007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 157107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 157307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 157507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 157807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 158407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1590d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1591d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1592d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 159607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1598655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1601655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 160207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 160407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1605655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 160607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 160807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1609655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 161007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 161107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 161207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 161307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 161507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1616d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1617d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1618d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 162007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1622655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16239d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 162407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 162507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 162770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1628655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 163070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1633d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1634d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1635d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 163807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1639655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16409d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 164207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 164307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 164407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 164507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 164607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 164770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 164870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1650d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1651d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1652d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 165307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1656655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 165770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 165870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1659f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t generate(const String16& name, int targetUid, int32_t flags) { 1660d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1661d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1662d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 166407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1666494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1667494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1668494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1669b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1670b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1671b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1672655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1673f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1674f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 167507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 167607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 167770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 167807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 168007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 168170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 168207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 168307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 168670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 168707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 168807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 169070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_keygen_params_t rsa_params; 169207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.modulus_size = 2048; 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.public_exponent = 0x10001; 169470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 169707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 169807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 169970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1700655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1701655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 170270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 170507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1706655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 170770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 170870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1709f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1710f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1711d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1712d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1713d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 171407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1717494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1718494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1719494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1720b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1721b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1722b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1723655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1724f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 172507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 172607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 172907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1730655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 173170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1732f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mKeyStore->importKey(data, length, filename.string(), callingUid, flags); 173370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 173470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1737d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1738d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1739d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 174007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 174107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 17429a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 174307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 174407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 174570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1746d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 174707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 174870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1749655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1750d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 175107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 175207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 175307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 175470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 175507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 175607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 175707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 175807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 176107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 176207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 176307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 176407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 176607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 176707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 177007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 177107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, length, out, outLength); 177207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 177307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 177407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 177507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 177670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 177870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 177970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 178007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 178107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1782d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1783d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1784d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 178507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 178607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 178770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1788655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17899d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 179007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 179107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 179207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 179407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 179507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 179607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 179770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1798655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1799494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 180007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 180107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 180207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 180507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 180607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 180707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 181007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 181107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 181307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 181407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 181507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 181670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 181707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 181807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, dataLength, signature, signatureLength); 181907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 182007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 182107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 182207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 182307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 182470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 182570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 182607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 182707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 182807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 182907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 183007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 183107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 183207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 183307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 183407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 183507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 183607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 183707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 1838d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1839d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1840d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 184107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 184207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 184370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 184407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 184507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 184670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1847d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 184870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1849655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 185007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 185107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 185207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 185307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 185470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 185507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 185607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 185707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 185807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 185970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 186007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 186107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 186207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 186307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1864344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 186507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 186607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root pubkeyLength); 186707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 186807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 186907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1870344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 187107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1872344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1873344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1874494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 1875d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1876d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1877d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 187807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 187907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1880344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1881494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1882494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1883494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1884b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1885b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1886b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 188707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1888655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 1889344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 189007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1891655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 1892655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 189307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 189407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 189507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1896a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 189707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 1898a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 189907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 190007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 190107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 190207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 190307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 190407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair != NULL) { 190507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 190607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 190707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1910a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 191107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 191207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 191307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1914a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 191507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1916a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 191707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 191807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 1919d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1920d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1921d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 192207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 192307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 192407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1925655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 19269d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 192707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 192807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 192907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 193007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 193107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1932655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 193307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1934655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 193507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 193607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 193707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1938655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 193907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1940a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 194107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 194207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 1943d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1944d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1945d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 194607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 194707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1949655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 19509d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 195107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 195207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 195307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 195407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 195507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1956655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 195707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1958655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 195907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 196007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1962655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 1963a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 196407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 196507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 1966d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1967d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1968d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 196936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 197007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 197107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 197207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1973655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 197407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1975655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 1976655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 197736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 1978a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 197907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1980655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 198107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 1982655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 198336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 198407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 198707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 198807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 198907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 1990655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 199136a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 199207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 199436a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 1995a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 199607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1997d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 1998d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 19990225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2000d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!has_permission(callingUid, P_DUPLICATE)) { 2001d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 20020225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 20030225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20040225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2005655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20060225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2007d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 20080225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 20090225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20100225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2011d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2012d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2013d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2014d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 20150225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 20160225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20170225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2018d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2019d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2020d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 20210225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2022d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2023d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2024d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2025d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2026d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2027d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 20280225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2029d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2030d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2031d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2032d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 20330225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20340225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2035d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2036655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2037d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2038d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2039655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, srcUid)); 20400225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2041655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2042655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 20430225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 20440225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20450225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2046d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2047655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2048655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 2049d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2050d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 20510225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2052d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2053655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, callingUid); 20540225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 20550225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 20568ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root int32_t is_hardware_backed() { 20578ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root return mKeyStore->isHardwareBacked() ? 1 : 0; 20588ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 20598ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2060a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root int32_t clear_uid(int64_t targetUid) { 2061a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2062a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!has_permission(callingUid, P_CLEAR_UID)) { 2063a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2064a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2065a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2066a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2067655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 2068a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!isKeystoreUnlocked(state)) { 2069a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGD("calling clear_uid in state: %d", state); 2070a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return state; 2071a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2072a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2073a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2074a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2075655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2076a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2077a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2078a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2079655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(callingUid); 2080655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2081a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2082655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2083a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2084a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2085a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2086655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2087655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", static_cast<uid_t>(targetUid)); 2088a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2089a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2090a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2091a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2092a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2093655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2094655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2095a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2096a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2097a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2098655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2099655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2100655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2101655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2102655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2103655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2104655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2105655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2106a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2107655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2108a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2109655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, callingUid) 2110655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2111655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2112a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2113a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2114a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2115a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2116a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 2117a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair != NULL) { 2118a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2119a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2120655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2121a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2122a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2123a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2124a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 21255f53124250025d3113c9c598a2f101330144b10cKenny Root if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) { 2126a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2127655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2128a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2129a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2130a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2131a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2132a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2133a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2134a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 21369d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 21379d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 21389d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 21399d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 21409d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 21419d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 21429d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 21439d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 21449d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2145a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 214607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 214707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 214807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 214907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2151a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2154a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2155a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2164a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 216670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 216770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 216870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 216970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 217070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 217170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 217270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 217370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2174655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 217507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 217607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 217707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 217807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 217907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 218007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2181a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 218270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 218307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 218407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 218507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 218607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 218707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 218870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 218907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2192