keystore.cpp revision eaabae9bf8ff0873b0ece2a835f71ee6c6b49437
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 { 139d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_TEST = 1 << 0, 140d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GET = 1 << 1, 141d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_INSERT = 1 << 2, 142d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DELETE = 1 << 3, 143d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_EXIST = 1 << 4, 144d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SAW = 1 << 5, 145d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_RESET = 1 << 6, 146d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_PASSWORD = 1 << 7, 147d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_LOCK = 1 << 8, 148d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_UNLOCK = 1 << 9, 149d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_ZERO = 1 << 10, 150d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SIGN = 1 << 11, 151d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_VERIFY = 1 << 12, 152d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GRANT = 1 << 13, 153d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DUPLICATE = 1 << 14, 154a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root P_CLEAR_UID = 1 << 15, 15507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 15607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 15807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 166eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */ 167eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = { 168eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "test", 169eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "get", 170eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "insert", 171eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "delete", 172eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "exist", 173eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "saw", 174eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "reset", 175eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "password", 176eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "lock", 177eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "unlock", 178eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "zero", 179eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "sign", 180eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "verify", 181eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "grant", 182eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "duplicate", 183eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "clear_uid" 184eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}; 185eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 18607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 18707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 18807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 18907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 19007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 19107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 19207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 19307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 19407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 19507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 19607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 19707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 19807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 199eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx; 200eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled; 201eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 202eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) { 203eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn unsigned int index = ffs(perm); 204eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) { 205eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return perm_labels[index - 1]; 206eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 207eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("Keystore: Failed to retrieve permission label.\n"); 208eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn abort(); 209eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 210eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 211eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 212655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 213655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 214655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 215655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 216655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 217655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 218655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 219655b958eb2180c7c06889f83f606d23421bf038cKenny Root 220655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 221655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 222655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 223655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 224655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 225655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 226655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 227655b958eb2180c7c06889f83f606d23421bf038cKenny Root 228eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid) { 229eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!ks_is_selinux_enabled) { 230eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return true; 231eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 232eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 233eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn char *sctx = NULL; 234eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *selinux_class = "keystore_key"; 235eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *str_perm = get_perm_label(perm); 236eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 237eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!str_perm) { 238eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 239eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 240eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 241eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getpidcon(spid, &sctx) != 0) { 242eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Failed to get source pid context.\n"); 243eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 244eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 24566dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 246eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm, 247eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn NULL) == 0; 248eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn freecon(sctx); 249eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return allowed; 250eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 251eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 252eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) { 253655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 254655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 255655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 256655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 257655b958eb2180c7c06889f83f606d23421bf038cKenny Root 25807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 25907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 26007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 261eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (user.perms & perm) && 262eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 26307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 26407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 26507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 266eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (DEFAULT_PERMS & perm) && 267eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 26807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 26907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 270494689083467ec372a58f094f041c8f102f39393Kenny Root/** 271494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 272494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 273494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 274494689083467ec372a58f094f041c8f102f39393Kenny Root */ 27507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 27607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 27707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 27807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 27907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 28007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 286494689083467ec372a58f094f041c8f102f39393Kenny Root/** 287494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 288494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 289494689083467ec372a58f094f041c8f102f39393Kenny Root */ 290494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 291494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 292494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 293494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 294494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 295494689083467ec372a58f094f041c8f102f39393Kenny Root } 296494689083467ec372a58f094f041c8f102f39393Kenny Root } 297494689083467ec372a58f094f041c8f102f39393Kenny Root 298494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 299494689083467ec372a58f094f041c8f102f39393Kenny Root} 300494689083467ec372a58f094f041c8f102f39393Kenny Root 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 308655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 309655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 310655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 311655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 312655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 313655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 314655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 315655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 316655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 317655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 318655b958eb2180c7c06889f83f606d23421bf038cKenny Root 31907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 32007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 32107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 323655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 327655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 328655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 33270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 33370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 33470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 33507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 33607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 33707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 33807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 33907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 34007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 34107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 34207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 34307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 34407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 34507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 34607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 34707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 34807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 34907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 35007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 35107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 35207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 35307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 35407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 35507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 35607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 35707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 35807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 35907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 36007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 36107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 36207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 36307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 36407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 36607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 375150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 3765281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 377150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 388150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 389150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 390150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 391150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 403150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 410150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 411150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4185187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 430822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 431f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 435822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 436822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 437822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 438822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 439822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 440822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 441822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 442822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 443822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 444822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 445822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 446822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 447822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 448822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 450822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 452f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 463d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 465822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 469f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 471a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 47307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 47407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 48107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 483f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 484ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 485ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 486ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 487ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 488ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4975187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5015187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5055187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 5065187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 5075187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 5085187818895c4c5f650a611c40531b1dff7764c18Kenny Root 5095187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 513822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 514822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 515822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 516822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 517f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 518f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 519f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 520f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 521f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 522f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 523f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 524f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 525f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 526f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 527f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 528f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 529f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 530f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 531f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 532f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 53317208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 53417208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 53517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 53617208e0de5a42722901d803118745cca25fd10c1Kenny Root 53717208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 53817208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 53917208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 54017208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 54117208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 54217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 54317208e0de5a42722901d803118745cca25fd10c1Kenny Root } 54417208e0de5a42722901d803118745cca25fd10c1Kenny Root 545822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 546822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 547822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 548822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 549822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 550822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 551822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 552822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 553822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 554822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 555822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 556822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 557f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 558f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 559f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 560f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 561f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 562f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 563f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 564f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 565f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 566f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 567f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 568f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 585f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 586f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 587f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 588f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 589f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 598150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 599150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 600150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 601150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 609150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 613150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 614150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 615150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 616150ca934edb745de3666a6492b039900df228ff0Kenny Root } 617150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 620f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 621f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 622150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 623150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 633f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 634f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 635f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 636f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 637f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 644f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 647f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 648f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 649f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 650f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 651f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 652f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 653f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 654f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 655f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 656f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 657f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 658f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 659f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 660f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 661f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 662f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 663f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 67507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 682655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 683655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 684655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 685655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 686655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 687655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 68870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 689655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 690655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 691655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 692655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 69370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 694655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 695655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 696655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 697655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 698655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 699655b958eb2180c7c06889f83f606d23421bf038cKenny Root 700655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 70570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 706655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 707655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 708655b958eb2180c7c06889f83f606d23421bf038cKenny Root 709655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 710655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 711655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 712655b958eb2180c7c06889f83f606d23421bf038cKenny Root 713655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 714655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 715655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 716655b958eb2180c7c06889f83f606d23421bf038cKenny Root 717655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 718655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 719655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 720655b958eb2180c7c06889f83f606d23421bf038cKenny Root 721655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 722655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 723655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 724655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 725655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7285187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7325187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 736655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 737655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 738655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 739655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 74170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 74270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 743655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 744655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 75207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 755655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 760822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 761f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 765655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 766150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 773a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 789f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 790f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 792f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 797655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 800655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 822655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 823655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 824655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 826655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 827655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 828655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 830655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 831655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 835a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 836655b958eb2180c7c06889f83f606d23421bf038cKenny Root 837655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 839655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 840655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 841655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 843655b958eb2180c7c06889f83f606d23421bf038cKenny Root 844655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 845655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 846655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 847655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 848655b958eb2180c7c06889f83f606d23421bf038cKenny Root 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's UID. 850655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 851655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 852655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 854655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root 856655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip if this is not our user. 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_user_id(thisUid) != mUserId) { 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 859655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root 861655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 867655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root 925655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root 930655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 931655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 944c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mGrants.clear(); 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 950c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mMasterKeys.clear(); 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root 957655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root 963655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 964655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 965655b958eb2180c7c06889f83f606d23421bf038cKenny Root 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 977655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 983655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 984655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 985655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 986655b958eb2180c7c06889f83f606d23421bf038cKenny Root 987655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 988a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 989655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 990655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 991655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 992655b958eb2180c7c06889f83f606d23421bf038cKenny Root 993655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 994a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 995655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 996655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 997655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 998655b958eb2180c7c06889f83f606d23421bf038cKenny Root 999655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 1000a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1001655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1002655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 1003655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 1004655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1008655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1009655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 1014655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 1015655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (userState == NULL) { 1016655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1017655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1018655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1019655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 1020a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 1021a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 1022a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 1023a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1024a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 1025655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(filename, sizeof(filename), "%u_", uid); 1028655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1029a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1031655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1032655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1033655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1034655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1035655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1036655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1037655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1038655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1039655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1040655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(file->d_name, filename, n)) { 1041a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 1043a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1044a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1045a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 1046a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 1047a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1048a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1049655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1052655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 1053a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1054a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 1056655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1057f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1058f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 1059822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1060822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1061822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1062822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1063822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 106407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1065cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1066cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1067cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1068cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1069655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 1070655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 1071f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1072f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1073cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1074cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1075cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1076822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1077822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 107817208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 107917208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 108017208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 108117208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 108217208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 108317208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 108417208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 108517208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 108617208e0de5a42722901d803118745cca25fd10c1Kenny Root uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 108717208e0de5a42722901d803118745cca25fd10c1Kenny Root 108817208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 108917208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 109017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 109117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid); 109217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 109317208e0de5a42722901d803118745cca25fd10c1Kenny Root } 109417208e0de5a42722901d803118745cca25fd10c1Kenny Root 1095d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1096822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1097822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1098822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1099822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1101a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1102a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1103655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1104655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1105f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1106f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1107a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1108a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 110907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1110655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1111655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1112655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 111307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1114a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1115655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 111670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 111770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 111870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 111907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1120655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1121655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1124655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1125655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 112870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 112970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 113070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1132a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1133a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 113470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1136f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1137f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1138822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1139822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1140822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1141822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1142822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1143822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1144822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1145822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1146822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 114717208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 114807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1149822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 115017208e0de5a42722901d803118745cca25fd10c1Kenny Root // If this is an old device HAL, try to fall back to an old version 115117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (mDevice->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_2) { 115217208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength); 115317208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 115417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 115517208e0de5a42722901d803118745cca25fd10c1Kenny Root 115617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 115717208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 115817208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 115917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1160822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1161822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1162822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1163822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1164822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1165f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 116617208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1167f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1168655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1169822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1170822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 11711b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 11721b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 11731b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 11741b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 11751b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11761b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 11771b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 11781b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 11791b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 11801b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 11811b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 11821b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 11831b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11848ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 11858ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1186655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1187655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 118886b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 1189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1190655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1191655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1192655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1193655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1195655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1196655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1197655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 119886b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 1199655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1200655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1201655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1202655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1203655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 120470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1205655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 120686b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1207655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 120886b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1209655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1210655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1211655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 121286b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(), 121386b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1215655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1222655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1223655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1224655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1225655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1226655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1227655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1228655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1229655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1230655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1231655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1232655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1233655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1235655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1236655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1237655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1238655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1239655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1240655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1241655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1242655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1244655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1245655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1246a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1248655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1249655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1250655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1251655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1252655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1253655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1254655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1255655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1256655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1257655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1258655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1259655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1260655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1261a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1262655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1263a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1264a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1265655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1266655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1267655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 12681b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1269655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 127007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1271655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1272a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1273655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1274655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1275655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 127670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1277655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1278655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1279655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 128070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1281655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1282655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1283655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1284655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1285655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1286655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 128770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1288655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 128970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 129070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 129170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 129270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 129370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 129470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1298822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1299655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1300655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1301822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1302822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1303822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1304822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1305822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1309822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1310655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1311822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1312822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1313822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1314822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1315822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1316f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1317f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1318f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1319f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1320f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1321f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1322f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1323f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1324f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1325822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1326822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1327822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1328cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1329822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1330822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1331822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1332822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1333cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1334cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1336822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1343655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1349822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1350822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1351822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1352822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1353822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1354822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1355822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1356822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1357822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1358822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1359822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1360822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1361822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1362822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1363822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 136470c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 136570c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1366822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1367822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1368822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1369822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1370822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1371f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1372f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1373822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1374822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1375822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1376822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1378822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 137970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1385655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1387655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 139170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 139270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 140570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 140870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 140970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1415655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1417655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1418655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1420655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1421655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1422655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1423655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1424655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1425655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1426655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1427655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1428655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1429655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1430655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1431655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1432655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1433655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1434655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1435655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1436655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1437655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1438655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1439655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1440655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1441655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1442655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1443655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1444655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1445655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1446655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1447655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1448655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1449655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1450655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1451655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1452655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1453655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1454655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1455655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1456655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1457655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1458655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1459655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1460655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1461655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1462655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1463655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1464655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1465655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1466655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1467655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1468655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1469655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1470655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1471655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1472655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1473655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1474655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1475655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1476655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1477655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1478655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 147970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1480655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 148170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1482655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1483655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 148470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14851b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 14861b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 148707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 148807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 148907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 149007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 149207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 149307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 149607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 149707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1500d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1501eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1502eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_TEST, spid)) { 1503d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 150407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1507655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1511d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1512eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1513eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 1514d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 151507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 151607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 151907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 152066dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 1521655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1522494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1524655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 152507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 152607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 152707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 152807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 153007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 153107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 153207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1537f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1538f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1539eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1540d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1541eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1542d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1546f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1547f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1548f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1549f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1550f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1551f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1552494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1553494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1554494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1555b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1556b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1557b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 155807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1559655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1562ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1563ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 1564fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(filename.string(), &keyBlob, targetUid); 1565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1567494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1568d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1569eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1570eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 1571d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 157207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 157307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 157407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1575494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1576494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1577494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1578b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1579b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1580b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 158107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1582655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1583298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 158407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1585655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1586fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid); 158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1591298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1592298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1593494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1594d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1595eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1596eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_EXIST, spid)) { 1597d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 159807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1601494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1602494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1603494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1604b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1605b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1606b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 160707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1608655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 160907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1610655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 161107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 161207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 161307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1614298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1615298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1616494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1617d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1618eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1619eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SAW, spid)) { 1620d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 162207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1624494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1625494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1626494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1627b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1628b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1629b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1630655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1631655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1633655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 163407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 163507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1638655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1639655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 164207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1643655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1644655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1645655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1646655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1647655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1649655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1650655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1652655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1653655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 165507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 165607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 165707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 165807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 165907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 166107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 166207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 166407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 166507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 166907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 167007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1671298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1672298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 167307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1674d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1675eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1676eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_RESET, spid)) { 1677d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 167807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1681655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 168307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 168607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 168807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 169807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 170507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 170607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 170707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 170807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 170907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1710d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1711eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1712eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_PASSWORD, spid)) { 1713d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 171407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 171707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1719655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 172007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 172107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1722655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 172307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 172507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1726655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 172907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1730655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 173107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 173407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1737d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1738eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1739eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_LOCK, spid)) { 1740d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 174107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 174207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1744655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17459d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 174607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 174707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 174807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1750655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 175107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 175270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1755d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1756eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1757eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_UNLOCK, spid)) { 1758d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 176007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1762655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17639d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 176407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 176507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 176607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 177070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 177170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 177207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1773d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1774eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1775eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_ZERO, spid)) { 1776d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 177970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1780655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 178170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 178270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 178396427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 178496427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1785d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1786eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1787eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1788d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 178907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 179007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1792494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1793494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1794494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1795b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1796b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1797b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1798655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1799f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1800f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 180107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 180207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 180507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 180607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 180717208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 180870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 181007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 181107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 181207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 181407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 181507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 181607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 181817208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 181996427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 182096427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 182196427baf0094d50047049d329b0779c3c910402cKenny Root 182296427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 182396427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 182496427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 182596427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 182696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 182796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 182896427baf0094d50047049d329b0779c3c910402cKenny Root } 182996427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 183096427baf0094d50047049d329b0779c3c910402cKenny Root 183196427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 183296427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 183396427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 183496427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 183596427baf0094d50047049d329b0779c3c910402cKenny Root 183696427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 183796427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 183896427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 183996427baf0094d50047049d329b0779c3c910402cKenny Root 184096427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 184196427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 184296427baf0094d50047049d329b0779c3c910402cKenny Root 184396427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 184496427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 184596427baf0094d50047049d329b0779c3c910402cKenny Root } else { 184696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 184796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 184896427baf0094d50047049d329b0779c3c910402cKenny Root } 184996427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 185096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 185196427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 185296427baf0094d50047049d329b0779c3c910402cKenny Root } 185396427baf0094d50047049d329b0779c3c910402cKenny Root 18541d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_DSA)) { 185517208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 185617208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 185717208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 185817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 185917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 186017208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 186196427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 186296427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 186396427baf0094d50047049d329b0779c3c910402cKenny Root 186496427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 186596427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 186696427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 186796427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 186896427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 186996427baf0094d50047049d329b0779c3c910402cKenny Root } 187096427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 187196427baf0094d50047049d329b0779c3c910402cKenny Root 18721d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_EC)) { 187317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 187417208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 187517208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 187617208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 187717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 187896427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 187996427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 188096427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 188196427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 188296427baf0094d50047049d329b0779c3c910402cKenny Root 188396427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 188496427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 188596427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 188696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 188796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 188896427baf0094d50047049d329b0779c3c910402cKenny Root } 188996427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 189096427baf0094d50047049d329b0779c3c910402cKenny Root 189196427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 18926489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin ALOGI("invalid number of arguments: %zu", args->size()); 189396427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 189496427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 189596427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 189696427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 189796427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 189896427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 189996427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 190096427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 190196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 190296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 190396427baf0094d50047049d329b0779c3c910402cKenny Root } 190496427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 190596427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 190696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 190796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 190896427baf0094d50047049d329b0779c3c910402cKenny Root } 190996427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 191096427baf0094d50047049d329b0779c3c910402cKenny Root } 191196427baf0094d50047049d329b0779c3c910402cKenny Root } 191296427baf0094d50047049d329b0779c3c910402cKenny Root 191396427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 191496427baf0094d50047049d329b0779c3c910402cKenny Root } else { 191596427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 191696427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 191796427baf0094d50047049d329b0779c3c910402cKenny Root } 191870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 191907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 192007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 192107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 192270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1923655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1924655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 192570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 192607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 192707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 192807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1929ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 193017208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 193117208e0de5a42722901d803118745cca25fd10c1Kenny Root 1932655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 193370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 193470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1935f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1936f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1937d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1938eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1939eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1940d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 194107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 194207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1944494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1945494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1946494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1947b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1948b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1949b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1950fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root State state = mKeyStore->getState(targetUid); 1951f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 195207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 195307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 195407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 195570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 195607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 195760898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 195870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1959fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->importKey(data, length, filename.string(), targetUid, flags); 196070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 196170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 196207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 196307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1964d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1965eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1966eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SIGN, spid)) { 1967d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 196807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 196907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 19709a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 197107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 197207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 197370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1974d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 197507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 197670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1977655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1978d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 197907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 198007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 198107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 198407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 198507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 198707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 199007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 199107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 199207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 199370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 199407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 199507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 199607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 199707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 199817208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 199917208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 200017208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 200117208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 200217208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 200317208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 200417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 200507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 200607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 200707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 200807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 201170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 201270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 201407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 2015d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2016eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2017eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_VERIFY, spid)) { 2018d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 201907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 202007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 202170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2022655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20239d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 202407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 202507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 202607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 202770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 202807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 202907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 203007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 203170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2032655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2033494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 203407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 203507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 203607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 203770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 203907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 204007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 204107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 204270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 204307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 204607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 204707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 204807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 204907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 205070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 205117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 205217208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 205317208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 205417208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 205517208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 205617208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 205717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 205807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 205907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 206207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 206470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 206807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 207007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 207407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 2077d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2078eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2079eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2080d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 208207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 208407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 208507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 208670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2087d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 208870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2089655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 209007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 209107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 209207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 209507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 209607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 209707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 210007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 210107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2104344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 210517208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 210617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 210717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 210817208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 210917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 211017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 211117208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 211217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2116344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 211707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2118344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2119344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2120494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2121d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2122eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2123eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 2124d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 212507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 212607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2127344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2128494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2129494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2130494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2131b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2132b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2133b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2135fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 2136344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 2138655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 2139fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid); 214007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 214107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 214207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2143a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 2145a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 214607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 214707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 214807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 214907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 215117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 215307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 215807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 215907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 216007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 2163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 216407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 216507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2166d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2167eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2168eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2169d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 217007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 217107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 217207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2173655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21749d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 217507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 217607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 217707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 217807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 217907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2180655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 218107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2182655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 218307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 218407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 218507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2186655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 218707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 218907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 219007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2191d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2192eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2193eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2194d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 219507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 219607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2198655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21999d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 220007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 220107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 220207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 220307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 220407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2205655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 220607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2207655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 220907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 221007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2211655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 221307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 221407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2215d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2216eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2217eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2218d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 221936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 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) { 2226655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 222736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 222907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2230655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 223107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2232655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 223336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 223407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 223507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 223607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 223707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 223807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 223907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2240655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 224136a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 224207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 224307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 224436a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 224607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2247d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2248d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 22490225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2250eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2251eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DUPLICATE, spid)) { 2252d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 22530225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 22540225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22550225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2256655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22570225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2258d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 22590225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 22600225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22610225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2262d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2263d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2264d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2265d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 22660225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 22670225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22680225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2269d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2270d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2271d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2273d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2274d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2275d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2276d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2277d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2278d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22790225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2280d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2281d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2282d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2283d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22840225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22850225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2286d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2287655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2288d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2289d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2290fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid)); 22910225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2292655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2293655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 22940225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 22950225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22960225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2297d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2298655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2299fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root srcUid); 2300d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2301d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 23020225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2303d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2304fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, destUid); 23050225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23060225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 23071b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 23081b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 23098ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 23108ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2311fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int32_t clear_uid(int64_t targetUid64) { 2312fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root uid_t targetUid = static_cast<uid_t>(targetUid64); 2313a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2314eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2315eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_CLEAR_UID, spid)) { 2316a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2317a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2318a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2319a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2320655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 2321a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!isKeystoreUnlocked(state)) { 2322a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGD("calling clear_uid in state: %d", state); 2323a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return state; 2324a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2325a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2326fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (targetUid64 == -1) { 2327fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid = callingUid; 2328fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2329fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return ::PERMISSION_DENIED; 2330fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root } 2331fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root 2332a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2333a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2334655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2335a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2336a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2337a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2338fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 2339655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2340a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2341655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2342a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2343a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2344a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2345655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2346fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", targetUid); 2347a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2348a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2349a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2350a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2351a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2352655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2353655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2354a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2355a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2356a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2357655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2358655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2359655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2360655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2361655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2362655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2363655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2364655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2365a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2366655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2367a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2368fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, targetUid) 2369655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2370655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2371a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2372a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2373a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2374a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2375a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 237617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 2377a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2378a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2379655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2380a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2381a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2382a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2383a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23845f53124250025d3113c9c598a2f101330144b10cKenny Root if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) { 2385a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2386655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2387a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2388a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2389a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2390a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2391a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2392a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2393a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 239407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 23959d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 23969d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 23979d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 23989d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 23999d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 24009d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 24019d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 24029d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 24039d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 240507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 24061d448c074a86ef5d05a22fdf1358718976628a86Kenny Root bool isKeyTypeSupported(const keymaster_device_t* device, keymaster_keypair_t keyType) { 24071d448c074a86ef5d05a22fdf1358718976628a86Kenny Root const int32_t device_api = device->common.module->module_api_version; 24081d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) { 24091d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24101d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24111d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 24121d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 24131d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24141d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 24151d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 24161d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24171d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) { 24181d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24191d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24201d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24211d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 24221d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_DSA; 24231d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 24241d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_EC; 24251d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 24261d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 24271d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24281d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else { 24291d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return keyType == TYPE_RSA; 24301d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24311d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24321d448c074a86ef5d05a22fdf1358718976628a86Kenny Root 243307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 243407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 243507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 243607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 245270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 245370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 245470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 245570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 245670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 245770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 245870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2459eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ks_is_selinux_enabled = is_selinux_enabled(); 2460eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (ks_is_selinux_enabled) { 2461eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn union selinux_callback cb; 2462eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn cb.func_log = selinux_log_callback; 2463eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 2464eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getcon(&tctx) != 0) { 2465eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n"); 2466eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return -1; 2467eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2468eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 2469eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGI("SELinux: Keystore SELinux is disabled.\n"); 2470eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2471eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 247270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2473655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 247407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 247507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 247607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 247707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 247807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 247907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 248170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 248207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 248307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 248407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 248507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 248607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 248770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 248807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2491