keystore.cpp revision a39da5a226975f8b75f93de255a21d526ae8d334
1a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* 2a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Copyright (C) 2009 The Android Open Source Project 3a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 4a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * you may not use this file except in compliance with the License. 6a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * You may obtain a copy of the License at 7a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 8a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 10a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Unless required by applicable law or agreed to in writing, software 11a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * See the License for the specific language governing permissions and 14a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * limitations under the License. 15a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root */ 16a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root//#define LOG_NDEBUG 0 1807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#define LOG_TAG "keystore" 1907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h> 21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h> 22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h> 23a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h> 24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h> 25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h> 26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h> 27655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <errno.h> 28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 30822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 37a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 38822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 39a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 40a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 41822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 42a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h> 4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4517208e0de5a42722901d803118745cca25fd10c1Kenny Root#include <keymaster/softkeymaster.h> 4617208e0de5a42722901d803118745cca25fd10c1Kenny Root 4726cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h> 48655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h> 49655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h> 5070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 5107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 5207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 61eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn#include <selinux/android.h> 62eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 6396427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h" 6496427baf0094d50047049d329b0779c3c910402cKenny Root 65a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 66a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 68a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 69a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 70a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 71a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 72a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 73a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 74a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 75822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 7696427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete { 7796427baf0094d50047049d329b0779c3c910402cKenny Root void operator()(BIGNUM* p) const { 7896427baf0094d50047049d329b0779c3c910402cKenny Root BN_free(p); 7996427baf0094d50047049d329b0779c3c910402cKenny Root } 8096427baf0094d50047049d329b0779c3c910402cKenny Root}; 8196427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM; 8296427baf0094d50047049d329b0779c3c910402cKenny Root 83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 13407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 13507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 13607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 13707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 13807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 1394e865753346fc6a075966972a7a98051818859dbRobin Lee P_TEST = 1 << 0, 1404e865753346fc6a075966972a7a98051818859dbRobin Lee P_GET = 1 << 1, 1414e865753346fc6a075966972a7a98051818859dbRobin Lee P_INSERT = 1 << 2, 1424e865753346fc6a075966972a7a98051818859dbRobin Lee P_DELETE = 1 << 3, 1434e865753346fc6a075966972a7a98051818859dbRobin Lee P_EXIST = 1 << 4, 1444e865753346fc6a075966972a7a98051818859dbRobin Lee P_SAW = 1 << 5, 1454e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET = 1 << 6, 1464e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD = 1 << 7, 1474e865753346fc6a075966972a7a98051818859dbRobin Lee P_LOCK = 1 << 8, 1484e865753346fc6a075966972a7a98051818859dbRobin Lee P_UNLOCK = 1 << 9, 1494e865753346fc6a075966972a7a98051818859dbRobin Lee P_ZERO = 1 << 10, 1504e865753346fc6a075966972a7a98051818859dbRobin Lee P_SIGN = 1 << 11, 1514e865753346fc6a075966972a7a98051818859dbRobin Lee P_VERIFY = 1 << 12, 1524e865753346fc6a075966972a7a98051818859dbRobin Lee P_GRANT = 1 << 13, 1534e865753346fc6a075966972a7a98051818859dbRobin Lee P_DUPLICATE = 1 << 14, 1544e865753346fc6a075966972a7a98051818859dbRobin Lee P_CLEAR_UID = 1 << 15, 1554e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET_UID = 1 << 16, 1564e865753346fc6a075966972a7a98051818859dbRobin Lee P_SYNC_UID = 1 << 17, 1574e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD_UID = 1 << 18, 15807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 16607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 16707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */ 170eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = { 171eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "test", 172eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "get", 173eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "insert", 174eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "delete", 175eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "exist", 176eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "saw", 177eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "reset", 178eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "password", 179eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "lock", 180eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "unlock", 181eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "zero", 182eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "sign", 183eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "verify", 184eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "grant", 185eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "duplicate", 1864e865753346fc6a075966972a7a98051818859dbRobin Lee "clear_uid", 1874e865753346fc6a075966972a7a98051818859dbRobin Lee "reset_uid", 1884e865753346fc6a075966972a7a98051818859dbRobin Lee "sync_uid", 1894e865753346fc6a075966972a7a98051818859dbRobin Lee "password_uid", 190eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}; 191eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 19207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 19307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 19407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 19507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 19607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 19707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 19807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 19907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 20007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 20107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 20307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 20407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 205eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx; 206eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled; 207eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 208eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) { 209eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn unsigned int index = ffs(perm); 210eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) { 211eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return perm_labels[index - 1]; 212eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 213eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("Keystore: Failed to retrieve permission label.\n"); 214eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn abort(); 215eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 216eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 217eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 218655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 219655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 220655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 221655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 222655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 223655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 224655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 225655b958eb2180c7c06889f83f606d23421bf038cKenny Root 226655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 227655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 228655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 229655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 230655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 231655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 232655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 233655b958eb2180c7c06889f83f606d23421bf038cKenny Root 234eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid) { 235eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!ks_is_selinux_enabled) { 236eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return true; 237eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 238eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 239eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn char *sctx = NULL; 240eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *selinux_class = "keystore_key"; 241eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *str_perm = get_perm_label(perm); 242eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 243eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!str_perm) { 244eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 245eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 246eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 247eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getpidcon(spid, &sctx) != 0) { 248eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Failed to get source pid context.\n"); 249eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 250eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 25166dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 252eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm, 253eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn NULL) == 0; 254eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn freecon(sctx); 255eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return allowed; 256eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 257eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 258eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) { 259655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 260655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 261655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 262655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 263655b958eb2180c7c06889f83f606d23421bf038cKenny Root 26407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 26507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 26607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 267eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (user.perms & perm) && 268eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 26907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 27007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 27107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 272eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (DEFAULT_PERMS & perm) && 273eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 27407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 27507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 276494689083467ec372a58f094f041c8f102f39393Kenny Root/** 277494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 278494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 279494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 280494689083467ec372a58f094f041c8f102f39393Kenny Root */ 28107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 29007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 292494689083467ec372a58f094f041c8f102f39393Kenny Root/** 293494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 294494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 295494689083467ec372a58f094f041c8f102f39393Kenny Root */ 296494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 297494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 298494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 299494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 300494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 301494689083467ec372a58f094f041c8f102f39393Kenny Root } 302494689083467ec372a58f094f041c8f102f39393Kenny Root } 303494689083467ec372a58f094f041c8f102f39393Kenny Root 304494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 305494689083467ec372a58f094f041c8f102f39393Kenny Root} 306494689083467ec372a58f094f041c8f102f39393Kenny Root 307007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root/** 308007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * Allow the system to perform some privileged tasks that have to do with 309007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * system maintenance. This should not be used for any function that uses 310007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * the keys in any way (e.g., signing). 311007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root */ 312007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Rootstatic bool is_self_or_system(uid_t callingUid, uid_t targetUid) { 313007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root return callingUid == targetUid || callingUid == AID_SYSTEM; 314007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root} 315007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 323655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 324655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 325655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 326655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 327655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 328655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 329655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 330655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 331655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 332655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 333655b958eb2180c7c06889f83f606d23421bf038cKenny Root 33407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 33507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 33607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 338655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 342655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 343655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 34770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 34870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 34970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 35007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 35107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 35207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 35307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 35407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 35507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 35607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 35707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 35807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 35907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 36007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 36107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 36207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 36307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 36407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 36507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 36607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 36707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 37707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 37907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 38107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 390150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 3915281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 392150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 403150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 404150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 405150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 406150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 418150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 425150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 426150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4335187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 445822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 446f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 450822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 452822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 454822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 460822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 461822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 463822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 465822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 467f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 471a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 478d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 483822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 484f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 48807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 48907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 495822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 49607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 497822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 498f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 499ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 500ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 501ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 502ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 503ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5125187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5165187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5205187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 5215187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 5225187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 5235187818895c4c5f650a611c40531b1dff7764c18Kenny Root 5245187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 528822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 529822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 530822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 531822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 532f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 533f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 534f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 535f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 536f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 537f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 538f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 539f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 540f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 541f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 542f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 543f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 544f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 545f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 546f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 547f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 54817208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 54917208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 55017208e0de5a42722901d803118745cca25fd10c1Kenny Root } 55117208e0de5a42722901d803118745cca25fd10c1Kenny Root 55217208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 55317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 55417208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 55517208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 55617208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 55717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 55817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 55917208e0de5a42722901d803118745cca25fd10c1Kenny Root 560822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 561822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 562822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 563822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 564822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 565822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 566822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 567822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 568822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 569822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 570822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 571822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 572f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 573f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 574f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 575f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 576f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 577f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 578f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 579f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 580f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 581f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 582f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 583f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 600f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 601f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 602f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 603f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 604f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 605f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 606f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 607f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 613150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 614150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 615150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 616150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 624150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 628150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 629150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 630150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 631150ca934edb745de3666a6492b039900df228ff0Kenny Root } 632150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 635f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 636f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 637150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 638150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 648f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 649f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 650f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 651f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 652f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 659f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 662f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 663f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 664f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 665f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 666f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 667f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 668f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 669f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 670f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 671f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 672f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 673f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 674f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 675f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 676f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 677f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 678f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 69007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 697655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 698655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 699655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 700655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 701655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 702655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 70370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 704655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 705655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 706655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 707655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 70870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 709655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 710655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 711655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 712655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 713655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 714655b958eb2180c7c06889f83f606d23421bf038cKenny Root 715655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 72070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 721655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 722655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 723655b958eb2180c7c06889f83f606d23421bf038cKenny Root 724655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 725655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 726655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 727655b958eb2180c7c06889f83f606d23421bf038cKenny Root 728655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 729655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 730655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 731655b958eb2180c7c06889f83f606d23421bf038cKenny Root 732655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 733655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 734655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 735655b958eb2180c7c06889f83f606d23421bf038cKenny Root 736655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 737655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 738655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 739655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7435187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7475187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 751655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 752655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 753655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 754655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 755655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 75670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 75770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 758655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 759655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 762655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 76707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7704e865753346fc6a075966972a7a98051818859dbRobin Lee ResponseCode copyMasterKey(UserState* src) { 7714e865753346fc6a075966972a7a98051818859dbRobin Lee if (mState != STATE_UNINITIALIZED) { 7724e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7734e865753346fc6a075966972a7a98051818859dbRobin Lee } 7744e865753346fc6a075966972a7a98051818859dbRobin Lee if (src->getState() != STATE_NO_ERROR) { 7754e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7764e865753346fc6a075966972a7a98051818859dbRobin Lee } 7774e865753346fc6a075966972a7a98051818859dbRobin Lee memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES); 7784e865753346fc6a075966972a7a98051818859dbRobin Lee setupMasterKeys(); 7794e865753346fc6a075966972a7a98051818859dbRobin Lee return ::NO_ERROR; 7804e865753346fc6a075966972a7a98051818859dbRobin Lee } 7814e865753346fc6a075966972a7a98051818859dbRobin Lee 782655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 787822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 788f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 791655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 792655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 793150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 816f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 817f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 819f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 824655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 827655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 835a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 840a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 841a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 842a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 850655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 851655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 854655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 863655b958eb2180c7c06889f83f606d23421bf038cKenny Root 864655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 872931fac098f2ae35aa1da26ced57962c9a21f95cfKenny Root if (file->d_name[0] == '.' && strcmp(".masterkey", file->d_name)) { 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 877a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 878a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 879a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 880a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 881a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 882655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root 940655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root 945655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 946655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 957655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 959c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mGrants.clear(); 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 963655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 964655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 965c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mMasterKeys.clear(); 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 977655b958eb2180c7c06889f83f606d23421bf038cKenny Root 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 983655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 984655b958eb2180c7c06889f83f606d23421bf038cKenny Root 985655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 986655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 987655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 988655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 989655b958eb2180c7c06889f83f606d23421bf038cKenny Root 9904e865753346fc6a075966972a7a98051818859dbRobin Lee ResponseCode copyMasterKey(uid_t src, uid_t uid) { 9914e865753346fc6a075966972a7a98051818859dbRobin Lee UserState *userState = getUserState(uid); 9924e865753346fc6a075966972a7a98051818859dbRobin Lee UserState *initState = getUserState(src); 9934e865753346fc6a075966972a7a98051818859dbRobin Lee return userState->copyMasterKey(initState); 9944e865753346fc6a075966972a7a98051818859dbRobin Lee } 9954e865753346fc6a075966972a7a98051818859dbRobin Lee 996655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 99750122db50bcb6c1aab50ef235c8f9d264b50e97aRobin Lee UserState* userState = getUserState(uid); 998655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 999655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1000655b958eb2180c7c06889f83f606d23421bf038cKenny Root 10014e865753346fc6a075966972a7a98051818859dbRobin Lee 1002655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 100350122db50bcb6c1aab50ef235c8f9d264b50e97aRobin Lee UserState* userState = getUserState(uid); 1004655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 1008a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1009655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 1014a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1015655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1016655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 1017655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1018655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1019655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 1020a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1021655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1022655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 1023655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 1024655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1025655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1028655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1029655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 1031655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1032655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1033655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 1034655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 103531e27468b6d822adbd2aec9219a68c206aa6957cKenny Root if (userState == NULL || userState->getState() == STATE_UNINITIALIZED) { 1036655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1037655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1038655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1039655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 1040a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 1041a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root 104431e27468b6d822adbd2aec9219a68c206aa6957cKenny Root bool result = true; 104531e27468b6d822adbd2aec9219a68c206aa6957cKenny Root struct dirent* file; 1046a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 1047655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1048655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1049655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1052655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1053655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1054655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1056655b958eb2180c7c06889f83f606d23421bf038cKenny Root 105731e27468b6d822adbd2aec9219a68c206aa6957cKenny Root result = false; 105831e27468b6d822adbd2aec9219a68c206aa6957cKenny Root break; 1059a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1060a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 1061a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 1062a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1063a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1064655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 1065655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1066655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1067655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 1068a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1069a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1070655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 1071655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1072f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1073f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 1074822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1075822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1076822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1077822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1078822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 107907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1080cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1081cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1082cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1083cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1084655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 1085655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 1086f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1087f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1088cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1089cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1090cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1091822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1092822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 109317208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 109417208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 109517208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 109617208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 109717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 109817208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 109917208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 110017208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 110117208e0de5a42722901d803118745cca25fd10c1Kenny Root uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 110217208e0de5a42722901d803118745cca25fd10c1Kenny Root 110317208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 110417208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 110517208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 110617208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid); 110717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 110817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 110917208e0de5a42722901d803118745cca25fd10c1Kenny Root 1110d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1111822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1112822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1113822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1114822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1115822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1116a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1117a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1118655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1119655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1120f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1121f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1122a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1123a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 112407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1125655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 112807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1129a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1130655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 113170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 113407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1135655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1136655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1137655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1138655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1139655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1140655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1141655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1142655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 114370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 114470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 114570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 114670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1147a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1148a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 114970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 115070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1151f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1152f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1153822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1154822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1155822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1156822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1157822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1158822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1159822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1160822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1161822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 116217208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 116307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1164822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 1165a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root /* 1166a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * Maybe the device doesn't support this type of key. Try to use the 1167a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * software fallback keymaster implementation. This is a little bit 1168a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * lazier than checking the PKCS#8 key type, but the software 1169a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * implementation will do that anyway. 1170a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root */ 1171a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength); 1172a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root isFallback = true; 117317208e0de5a42722901d803118745cca25fd10c1Kenny Root 117417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 117517208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 117617208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 117717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1178822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1179822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1180822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1181822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1182822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1183f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 118417208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1185f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1186655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1187822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1188822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 11891b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 11901b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 11911b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 11921b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 11931b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11941b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 11951b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 11961b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 11971b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 11981b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 11991b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 12001b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 12011b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 12028ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 12038ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1204655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1205655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 120686b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 1207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1208655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1209655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1210655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1211655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1213655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1215655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 121686b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 1217655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1220655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1221655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 122270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1223655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 122486b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1225655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 122686b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1227655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1228655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1229655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 123086b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(), 123186b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1232655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1233655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1236655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1237655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1240655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1241655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1242655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1243655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1244655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1245655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1246655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1247655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1248655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1249655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1250655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1251655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1252a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1253655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1254655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1255655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1256655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1257655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1258655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1259655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1260655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1261a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1262655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1263655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1264a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1265a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1266655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1267655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1268655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1269655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1270655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1271655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1272655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1273655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1274655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1275655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1276655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1277655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1278655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1279a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1280655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1283655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1284655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1285655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 12861b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1287655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 128807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1289655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1290a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1291655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1292655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1293655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 129470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1295655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1296655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1297655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 129870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1299655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1300655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1301655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1302655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1303655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1304655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 130570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1306655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 130770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 130870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 130970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 131070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 131170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 131270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1313822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1314822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1315822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1316822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1317655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1318655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1319822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1320822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1321822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1322822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1323822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1324822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1325822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1326822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1327822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1328655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1329822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1330822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1331822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1332822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1333822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1334f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1335f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1336f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1337f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1338f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1339f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1340f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1341f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1342f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1346cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1349822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1350822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1351cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1352cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1353822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1354822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1355822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1356822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1357822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1358822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1359822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1360822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1362822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1363822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1364822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1365822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1366822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1367822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1368822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1369822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1370822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1371822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1372822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1373822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1374822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1375822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1376822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1377822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1378822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1379822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1380822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1381822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 138270c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 138370c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1384822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1385822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1386822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1387822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1388822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1389f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1390f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1391822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1392822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1393822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1394822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1396822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 139770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 140970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 141070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1415655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1417655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1418655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1420655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1421655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1422655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 142370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1424655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1425655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 142670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 142770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1428655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1429655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1430655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1431655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1432655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1433655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1434655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1435655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1436655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1437655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1438655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1439655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1440655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1441655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1442655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1443655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1444655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1445655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1446655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1447655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1448655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1449655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1450655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1451655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1452655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1453655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1454655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1455655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1456655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1457655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1458655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1459655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1460655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1461655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1462655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1463655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1464655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1465655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1466655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1467655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1468655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1469655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1470655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1471655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1472655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1473655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1474655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1475655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1476655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1477655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1478655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1479655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1480655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1481655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1482655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1483655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1484655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1485655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1486655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1487655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1488655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1489655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1490655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1491655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1492655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1493655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1494655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1495655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1496655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 149770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1498655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 149970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1500655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1501655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 150270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 15031b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 15041b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 150507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 150607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 150707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 150807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 150907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 151107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 151507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1518d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1519eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1520eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_TEST, spid)) { 1521d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 152207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1525655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 152807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1529d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1530eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1531eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 1532d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 153607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 153707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 153866dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 1539655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1540494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1542655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 154607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 155007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 155107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1555f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1556f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1557eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1558d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1559eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1560d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 156107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 156207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1564f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1565f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1566f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1567f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1568f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1569f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1570494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1571494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1572494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1573b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1574b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1575b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 157807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1580ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1581ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 1582fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(filename.string(), &keyBlob, targetUid); 1583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1585494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1586d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1587eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1588eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 1589d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1593494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1594494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1595494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1596b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1597b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1598b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1600655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1601298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 160207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1603655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1604fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid); 160507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 160607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 160707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1609298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1610298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1611494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1612d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1613eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1614eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_EXIST, spid)) { 1615d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 161607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 161707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1619494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1620494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1621494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1622b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1623b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1624b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 162507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1626655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1628655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 163107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1632298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1633298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1634494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1635d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1636eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1637eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SAW, spid)) { 1638d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 163907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1642494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1643494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1644494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1645b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1646b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1647b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1649655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 165007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 165207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 165307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 165507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1656655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1657655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 165807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 165907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1661655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1662655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1663655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1664655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1665655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1666655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1667655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1668655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1669655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1670655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1671655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 167207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 167307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 167407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 167507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 167607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 167707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 167807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 168007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 168107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 168207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 168307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 168607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 168707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 168807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1689298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1690298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1692d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1693eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1694eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_RESET, spid)) { 1695d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 169707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1699655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 170607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 170707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 170807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 170907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 171107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 171307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 171407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 171607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 171707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 172007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 172107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 172207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 172307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 172507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 172607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1728d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1729eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1730eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_PASSWORD, spid)) { 1731d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 173207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 173307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 173507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1737655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 173807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 173907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1740655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 174107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 174307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1744655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 174507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 174707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1748655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 174907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 175007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 175107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 175207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1755d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1756eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1757eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_LOCK, spid)) { 1758d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 176007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1762655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17639d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 176407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 176507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 176607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1768655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 177070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 177207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1773d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1774eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1775eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_UNLOCK, spid)) { 1776d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 177907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1780655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17819d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 178207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 178307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 178407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 178507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 178607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 178707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 178870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 178970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 179007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1791d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1792eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1793eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_ZERO, spid)) { 1794d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 179507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 179607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1798655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 179970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 180070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180196427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 180296427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1803d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1804eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1805eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1806d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 180707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 180807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1810494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1811494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1812494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1813b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1814b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1815b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1816655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1817f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1818f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 181907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 182007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 182170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 182207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 182307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 182407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 182517208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 182670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 182707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 182807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 182907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 183007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 183170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 183207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 183307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 183407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 183570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 183617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 183796427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 183896427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 183996427baf0094d50047049d329b0779c3c910402cKenny Root 184096427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 184196427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 184296427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 184396427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 184496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 184596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 184696427baf0094d50047049d329b0779c3c910402cKenny Root } 184796427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 184896427baf0094d50047049d329b0779c3c910402cKenny Root 184996427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 185096427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 185196427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 185296427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 185396427baf0094d50047049d329b0779c3c910402cKenny Root 185496427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 185596427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 185696427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 185796427baf0094d50047049d329b0779c3c910402cKenny Root 185896427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 185996427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 186096427baf0094d50047049d329b0779c3c910402cKenny Root 186196427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 186296427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 186396427baf0094d50047049d329b0779c3c910402cKenny Root } else { 186496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 186596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 186696427baf0094d50047049d329b0779c3c910402cKenny Root } 186796427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 186896427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 186996427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 187096427baf0094d50047049d329b0779c3c910402cKenny Root } 187196427baf0094d50047049d329b0779c3c910402cKenny Root 18721d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_DSA)) { 187317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 187417208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 187517208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 187617208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 187717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 187817208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 187996427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 188096427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 188196427baf0094d50047049d329b0779c3c910402cKenny Root 188296427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 188396427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 188496427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 188596427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 188696427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 188796427baf0094d50047049d329b0779c3c910402cKenny Root } 188896427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 188996427baf0094d50047049d329b0779c3c910402cKenny Root 18901d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_EC)) { 189117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 189217208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 189317208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 189417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 189517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 189696427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 189796427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 189896427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 189996427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 190096427baf0094d50047049d329b0779c3c910402cKenny Root 190196427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 190296427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 190396427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 190496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 190596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 190696427baf0094d50047049d329b0779c3c910402cKenny Root } 190796427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 190896427baf0094d50047049d329b0779c3c910402cKenny Root 190996427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 19106489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin ALOGI("invalid number of arguments: %zu", args->size()); 191196427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 191296427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 191396427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 191496427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 191596427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 191696427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 191796427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 191896427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 191996427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 192096427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 192196427baf0094d50047049d329b0779c3c910402cKenny Root } 192296427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 192396427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 192496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 192596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 192696427baf0094d50047049d329b0779c3c910402cKenny Root } 192796427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 192896427baf0094d50047049d329b0779c3c910402cKenny Root } 192996427baf0094d50047049d329b0779c3c910402cKenny Root } 193096427baf0094d50047049d329b0779c3c910402cKenny Root 193196427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 193296427baf0094d50047049d329b0779c3c910402cKenny Root } else { 193396427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 193496427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 193596427baf0094d50047049d329b0779c3c910402cKenny Root } 193670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 193707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 193807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 193907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1941655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1942655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 194370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 194407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 194507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 194607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1947ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 194817208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 194917208e0de5a42722901d803118745cca25fd10c1Kenny Root 1950655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 195170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 195270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1953f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1954f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1955d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1956eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1957eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1958d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 195907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 196007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1962494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1963494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1964494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1965b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1966b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1967b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1968fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root State state = mKeyStore->getState(targetUid); 1969f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 197007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 197107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 197207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 197370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 197407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 197560898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 197670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1977fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->importKey(data, length, filename.string(), targetUid, flags); 197870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 197970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 198107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1982d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1983eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1984eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SIGN, spid)) { 1985d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 198707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 19889a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 198907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 199007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 199170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1992d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 199470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1995655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1996d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 199707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 199807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 199907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 200207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 200307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 200407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 200507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 200807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 200907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 201007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 201307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 201407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 201617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 201717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 201817208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 201917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 202017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 202117208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 202217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 202307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 202407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 202507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 202607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 202770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 202807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 202970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 203070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 203207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 2033d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2034eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2035eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_VERIFY, spid)) { 2036d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 203707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 203807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 203970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2040655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20419d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 204207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 204307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 204570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 204607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 204707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 204807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 204970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2050655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2051494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 205207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 205307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 205407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 205570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 205607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 205807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 205907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 206207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 206870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206917208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 207017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 207117208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 207217208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 207317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 207417208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 207517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 207707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 207807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 208007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 208270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 208307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 208407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 208507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 208607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 208907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 209007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 209107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 209207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 2095d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2096eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2097eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2098d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 210007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 210470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2105d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 210670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2107655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 210807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 210907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 211007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 211107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 211607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 211807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 211907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2122344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 212317208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 212417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 212517208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 212617208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 212717208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 212817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 212917208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 213017208e0de5a42722901d803118745cca25fd10c1Kenny Root } 213107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 213207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 213307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2134344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2136344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2137344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2138494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2139d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2140eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2141eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 2142d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 214307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2145344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2146494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2147494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2148494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2149b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2150b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2151b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2153fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 2154344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 2156655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 2157fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid); 215807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 215907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 216007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 2163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 216407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 216507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 216607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 216707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 216807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 216917208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 217007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 217107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 217207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 217307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 217407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 217607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 217707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 217807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2179a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 218007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 2181a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 218207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 218307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2184d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2185eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2186eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2187d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 218807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 218907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2191655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21929d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 219307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 219407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 219507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 219707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2198655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 219907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2200655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 220107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 220207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 220307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2204655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 220507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 220707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2209d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2210eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2211eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2212d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 221307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 221407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 221507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2216655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22179d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 221807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 221907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 222007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 222107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 222207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2223655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 222407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2225655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 222607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 222707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 222807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2229655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 223107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 223207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2233d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2234eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2235eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2236d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 223736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 223807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 223907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 224007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2241655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 224207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2243655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2244655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 224536a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2246a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 224707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2248655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 224907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2250655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 225136a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 225207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 225307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 225407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 225507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 225607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 225707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2258655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 225936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 226007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 226107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 226236a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2263a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 226407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2265d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2266d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 22670225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2268eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2269eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DUPLICATE, spid)) { 2270d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 22710225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 22720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22730225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2274655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22750225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2276d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 22770225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 22780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22790225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2280d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2281d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2282d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2283d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 22840225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 22850225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22860225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2287d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2288d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2289d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22900225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2291d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2292d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2293d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2294d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2295d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2296d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22970225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2298d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2299d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2300d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2301d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 23020225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23030225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2304d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2305655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2306d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2307d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2308fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid)); 23090225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2310655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2311655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 23120225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 23130225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23140225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2315d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2316655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2317fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root srcUid); 2318d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2319d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 23200225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2321d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2322fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, destUid); 23230225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23240225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 23251b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 23261b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 23278ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 23288ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2329fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int32_t clear_uid(int64_t targetUid64) { 2330fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root uid_t targetUid = static_cast<uid_t>(targetUid64); 2331a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2332eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2333eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_CLEAR_UID, spid)) { 2334a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2335a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2336a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2337a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2338fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (targetUid64 == -1) { 2339fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid = callingUid; 2340007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root } else if (!is_self_or_system(callingUid, targetUid)) { 2341007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root ALOGW("permission denied for %d: clear_uid %d", callingUid, targetUid); 2342fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return ::PERMISSION_DENIED; 2343fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root } 2344fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root 2345a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2346a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2347655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2348a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2349a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2350a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2351fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 2352655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2353a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2354655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2355a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2356a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2357a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2358655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2359fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", targetUid); 2360a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2361a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2362a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2363a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2364a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2365655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2366655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2367a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2368a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2369a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2370655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2371655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2372655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2373655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2374655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2375655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2376655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2377655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2378a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2379655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2380a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2381fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, targetUid) 2382655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2383655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2384a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2385a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2386a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2387a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2388a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 238917208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 2390a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2391a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2392655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2393a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2394a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2395a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2396a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23975f53124250025d3113c9c598a2f101330144b10cKenny Root if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) { 2398a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2399655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2400a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2401a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2402a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2403a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2404a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2405a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2406a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 24074e865753346fc6a075966972a7a98051818859dbRobin Lee int32_t reset_uid(int32_t uid) { 24084e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 24094e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 24104e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_RESET_UID, spid)) { 24114e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: reset_uid %d", callingUid, uid); 24124e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24134e865753346fc6a075966972a7a98051818859dbRobin Lee } 24144e865753346fc6a075966972a7a98051818859dbRobin Lee if (callingUid != AID_SYSTEM) { 24154e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: reset_uid %d", callingUid, uid); 24164e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24174e865753346fc6a075966972a7a98051818859dbRobin Lee } 24184e865753346fc6a075966972a7a98051818859dbRobin Lee 24194e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->reset(uid) ? ::NO_ERROR : ::SYSTEM_ERROR; 24204e865753346fc6a075966972a7a98051818859dbRobin Lee } 24214e865753346fc6a075966972a7a98051818859dbRobin Lee 24224e865753346fc6a075966972a7a98051818859dbRobin Lee int32_t sync_uid(int32_t sourceUid, int32_t targetUid) { 24234e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 24244e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 24254e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_SYNC_UID, spid)) { 24264e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid); 24274e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24284e865753346fc6a075966972a7a98051818859dbRobin Lee } 24294e865753346fc6a075966972a7a98051818859dbRobin Lee if (callingUid != AID_SYSTEM) { 24304e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid); 24314e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24324e865753346fc6a075966972a7a98051818859dbRobin Lee } 24334e865753346fc6a075966972a7a98051818859dbRobin Lee if (sourceUid == targetUid) { 24344e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 24354e865753346fc6a075966972a7a98051818859dbRobin Lee } 24364e865753346fc6a075966972a7a98051818859dbRobin Lee 24374e865753346fc6a075966972a7a98051818859dbRobin Lee // Initialise user keystore with existing master key held in-memory 24384e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->copyMasterKey(sourceUid, targetUid); 24394e865753346fc6a075966972a7a98051818859dbRobin Lee } 24404e865753346fc6a075966972a7a98051818859dbRobin Lee 24414e865753346fc6a075966972a7a98051818859dbRobin Lee int32_t password_uid(const String16& pw, int32_t targetUid) { 24424e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 24434e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 24444e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_PASSWORD_UID, spid)) { 24454e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid); 24464e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24474e865753346fc6a075966972a7a98051818859dbRobin Lee } 24484e865753346fc6a075966972a7a98051818859dbRobin Lee if (callingUid != AID_SYSTEM) { 24494e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid); 24504e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24514e865753346fc6a075966972a7a98051818859dbRobin Lee } 24524e865753346fc6a075966972a7a98051818859dbRobin Lee 24534e865753346fc6a075966972a7a98051818859dbRobin Lee const String8 password8(pw); 24544e865753346fc6a075966972a7a98051818859dbRobin Lee 24554e865753346fc6a075966972a7a98051818859dbRobin Lee switch (mKeyStore->getState(targetUid)) { 24564e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_UNINITIALIZED: { 24574e865753346fc6a075966972a7a98051818859dbRobin Lee // generate master key, encrypt with password, write to file, initialize mMasterKey*. 24584e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->initializeUser(password8, targetUid); 24594e865753346fc6a075966972a7a98051818859dbRobin Lee } 24604e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_NO_ERROR: { 24614e865753346fc6a075966972a7a98051818859dbRobin Lee // rewrite master key with new password. 24624e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->writeMasterKey(password8, targetUid); 24634e865753346fc6a075966972a7a98051818859dbRobin Lee } 24644e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_LOCKED: { 24654e865753346fc6a075966972a7a98051818859dbRobin Lee // read master key, decrypt with password, initialize mMasterKey*. 24664e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->readMasterKey(password8, targetUid); 24674e865753346fc6a075966972a7a98051818859dbRobin Lee } 24684e865753346fc6a075966972a7a98051818859dbRobin Lee } 24694e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 24704e865753346fc6a075966972a7a98051818859dbRobin Lee } 24714e865753346fc6a075966972a7a98051818859dbRobin Lee 247207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 24739d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 24749d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 24759d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 24769d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 24779d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 24789d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 24799d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 24809d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 24819d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 248307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 24841d448c074a86ef5d05a22fdf1358718976628a86Kenny Root bool isKeyTypeSupported(const keymaster_device_t* device, keymaster_keypair_t keyType) { 24851d448c074a86ef5d05a22fdf1358718976628a86Kenny Root const int32_t device_api = device->common.module->module_api_version; 24861d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) { 24871d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24881d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24891d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 24901d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 24911d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24921d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 24931d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 24941d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24951d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) { 24961d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24971d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24981d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24991d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 25001d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_DSA; 25011d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 25021d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_EC; 25031d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 25041d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 25051d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 25061d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else { 25071d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return keyType == TYPE_RSA; 25081d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 25091d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 25101d448c074a86ef5d05a22fdf1358718976628a86Kenny Root 251107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 251207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 251307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 251407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 253070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 253170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 253270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 253370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 253470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 253570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 253670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2537eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ks_is_selinux_enabled = is_selinux_enabled(); 2538eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (ks_is_selinux_enabled) { 2539eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn union selinux_callback cb; 2540eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn cb.func_log = selinux_log_callback; 2541eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 2542eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getcon(&tctx) != 0) { 2543eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n"); 2544eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return -1; 2545eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2546eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 2547eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGI("SELinux: Keystore SELinux is disabled.\n"); 2548eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2549eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 255070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2551655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 255207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 255307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 255407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 255507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 255607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 255707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 255970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 256007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 256107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 256207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 256307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 256407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 256570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 256607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2569