keystore.cpp revision a25b2a397fff48dea7bce16af2065e6f5f043956
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 228a25b2a397fff48dea7bce16af2065e6f5f043956Chih-Hung Hsiehstatic 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 301e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root/** 302e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root * Allow the system to perform some privileged tasks that have to do with 303e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root * system maintenance. This should not be used for any function that uses 304e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root * the keys in any way (e.g., signing). 305e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root */ 306e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Rootstatic bool is_self_or_system(uid_t callingUid, uid_t targetUid) { 307e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root return callingUid == targetUid || callingUid == AID_SYSTEM; 308e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root} 309e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 317655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 318655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 319655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 320655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 321655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 322655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 323655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 324655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 325655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 326655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 327655b958eb2180c7c06889f83f606d23421bf038cKenny Root 32807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 32907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 33007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 332655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 336655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 337655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 34170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 34270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 34370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 34407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 34507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 34607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 34707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 34807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 34907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 35007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 35107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 35207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 35307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 35407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 35507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 35607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 35707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 35807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 35907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 36007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 36107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 36207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 36307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 36407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 36507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 36607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 36707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 384150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 3855281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 386150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 397150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 398150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 399150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 400150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 412150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 419150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 420150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4275187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 439822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 440f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 444822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 445822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 446822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 447822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 448822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 449822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 450822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 452822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 454822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 460822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 461f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 472d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 478f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 48207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 48307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 49007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 492f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 493ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 494ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 495ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 496ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 497ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5065187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5105187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5145187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 5155187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 5165187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 5175187818895c4c5f650a611c40531b1dff7764c18Kenny Root 5185187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 522822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 523822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 524822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 525822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 526f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 527f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 528f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 529f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 530f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 531f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 532f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 533f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 534f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 535f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 536f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 537f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 538f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 539f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 540f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 541f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 54217208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 54317208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 54417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 54517208e0de5a42722901d803118745cca25fd10c1Kenny Root 54617208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 54717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 54817208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 54917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 55017208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 55117208e0de5a42722901d803118745cca25fd10c1Kenny Root } 55217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 55317208e0de5a42722901d803118745cca25fd10c1Kenny Root 554822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 555822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 556822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 557822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 558822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 559822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 560822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 561822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 562822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 563822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 564822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 565822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 566f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 567f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 568f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 569f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 570f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 571f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 572f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 573f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 574f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 575f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 576f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 577f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 595f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 596f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 597f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 598f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 599f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 600f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 601f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 607150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 608150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 609150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 610150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 618150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 622150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 623150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 624150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 625150ca934edb745de3666a6492b039900df228ff0Kenny Root } 626150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 629f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 630f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 631150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 632150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 642f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 643f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 644f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 645f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 646f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 653f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 656f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 657f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 658f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 659f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 660f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 661f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 662f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 663f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 664f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 665f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 666f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 667f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 668f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 669f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 670f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 671f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 672f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 68407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 691655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 692655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 693655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 694655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 695655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 696655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 69770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 698655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 699655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 700655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 701655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 70270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 703655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 704655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 705655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 706655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 707655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 708655b958eb2180c7c06889f83f606d23421bf038cKenny Root 709655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 71470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 715655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 716655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 717655b958eb2180c7c06889f83f606d23421bf038cKenny Root 718655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 719655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 720655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 721655b958eb2180c7c06889f83f606d23421bf038cKenny Root 722655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 723655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 724655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 725655b958eb2180c7c06889f83f606d23421bf038cKenny Root 726655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 727655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 728655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 729655b958eb2180c7c06889f83f606d23421bf038cKenny Root 730655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 731655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 732655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 733655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 734655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7375187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7415187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 745655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 746655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 748655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 749655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 75070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 75170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 752655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 753655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 756655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 76107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 769822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 770f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 774655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 775150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 792a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 798f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 799f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 801f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 806655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 809655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 831655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 832655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 835655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 836655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 837655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 839655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 840655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 841a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 845655b958eb2180c7c06889f83f606d23421bf038cKenny Root 846655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 848655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 850655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 851655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 852655b958eb2180c7c06889f83f606d23421bf038cKenny Root 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 854a71c9d6bb8b12b38a12fcd18321eb67e3b974be8Kenny Root if (file->d_name[0] == '.' && strcmp(".masterkey", file->d_name)) { 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 856655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 864655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 865655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root 922655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root 927655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 928655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 941c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mGrants.clear(); 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 947c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mMasterKeys.clear(); 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 957655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root 963655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 964655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 965655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 973b224f0ae07dd86cd7493bd497e1174db52b3782dRobin Lee UserState* userState = getUserState(uid); 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root 977655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 978b224f0ae07dd86cd7493bd497e1174db52b3782dRobin Lee UserState* userState = getUserState(uid); 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 983a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 984655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 985655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 986655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 987655b958eb2180c7c06889f83f606d23421bf038cKenny Root 988655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 989a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 990655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 991655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 992655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 993655b958eb2180c7c06889f83f606d23421bf038cKenny Root 994655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 995a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 996655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 997655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 998655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 999655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1000655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1001655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 1002655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1003655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1004655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1008655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 1009655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (userState == NULL) { 1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1014655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 1015a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 1016a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 1017a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 1018a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1019a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 1020655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1021655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 1022655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(filename, sizeof(filename), "%u_", uid); 1023655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1024a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 1025655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1028655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1029655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1031655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1032655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1033655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1034655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1035655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(file->d_name, filename, n)) { 1036a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 1037a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 1038a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1039a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1040a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 1041a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1043a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 1045655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1046655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1047655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 1048a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1049a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1052f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1053f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 1054822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1055822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1056822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1057822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1058822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 105907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1060cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1061cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1062cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1063cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1064655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 1065655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 1066f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1067f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1068cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1069cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1070cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1071822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1072822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 107317208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 107417208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 107517208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 107617208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 107717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 107817208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 107917208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 108017208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 108117208e0de5a42722901d803118745cca25fd10c1Kenny Root uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 108217208e0de5a42722901d803118745cca25fd10c1Kenny Root 108317208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 108417208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 108517208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 108617208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid); 108717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 108817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 108917208e0de5a42722901d803118745cca25fd10c1Kenny Root 1090d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1091822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1092822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1093822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1094822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1095822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1096a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1097a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1098655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1099655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1100f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1101f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1102a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1103a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 110407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1105655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1106655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1107655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 110807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1109a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1110655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 111170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 111270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 111370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 111407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1115655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1116655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1117655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1118655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1119655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1120655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1121655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 112370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 112470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 112570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 112670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1127a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1128a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 112970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1131f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1132f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1133822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1134822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1135822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1136822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1137822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1138822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1139822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1140822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1141822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 114217208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 114307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1144822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 114517208e0de5a42722901d803118745cca25fd10c1Kenny Root // If this is an old device HAL, try to fall back to an old version 114617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (mDevice->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_2) { 114717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength); 114817208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 114917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 115017208e0de5a42722901d803118745cca25fd10c1Kenny Root 115117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 115217208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 115317208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 115417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1155822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1156822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1157822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1158822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1159822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1160f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 116117208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1162f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1163655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1164822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1165822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 11661b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 11671b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 11681b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 11691b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 11701b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11711b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 11721b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 11731b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 11741b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 11751b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 11761b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 11771b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 11781b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 11798ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 11808ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1181655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1182655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 118386b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 1184a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1185655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1186655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1187655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1188655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1190655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1191655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1192655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 119386b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 1194655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1195655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1196655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1197655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1198655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 119970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1200655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 120186b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1202655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 120386b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1204655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1205655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1206655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 120786b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(), 120886b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1209655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1210655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1213655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1217655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1220655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1221655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1222655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1223655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1224655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1225655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1226655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1227655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1228655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1230655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1231655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1232655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1233655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1234655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1235655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1236655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1237655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1239655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1240655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1243655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1244655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1245655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1246655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1247655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1248655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1249655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1250655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1251655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1252655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1253655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1254655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1255655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1256a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1257655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1258a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1259a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1260655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1261655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1262655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 12631b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1264655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 126507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1266655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1267a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1268655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1269655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1270655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 127170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1272655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1273655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1274655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 127570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1276655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1277655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1278655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1279655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1280655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1281655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 128270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1283655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 128470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 128570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 128870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1294655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1295655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1298822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1299822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1301822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1302822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1303822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1304822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1305655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1309822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1310822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1311f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1312f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1313f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1314f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1315f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1316f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1317f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1318f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1319f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1320822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1321822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1322822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1323cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1324822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1325822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1326822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1327822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1328cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1329cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1330822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1331822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1332822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1333822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1334822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1336822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1338655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1349822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1350822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1351822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1352822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1353822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1354822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1355822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1356822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1357822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1358822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 135970c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 136070c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1361822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1362822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1363822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1364822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1365822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1366f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1367f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1368822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1369822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1370822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1371822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1372655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1373822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 137470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1376655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1385655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 138670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 138770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1391655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1392655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 140070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 140370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 140470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1409655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1415655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1417655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1418655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1420655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1421655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1422655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1423655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1424655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1425655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1426655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1427655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1428655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1429655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1430655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1431655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1432655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1433655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1434655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1435655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1436655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1437655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1438655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1439655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1440655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1441655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1442655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1443655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1444655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1445655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1446655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1447655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1448655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1449655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1450655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1451655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1452655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1453655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1454655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1455655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1456655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1457655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1458655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1459655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1460655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1461655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1462655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1463655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1464655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1465655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1466655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1467655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1468655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1469655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1470655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1471655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1472655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1473655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 147470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1475655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 147670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1477655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1478655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 147970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14801b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 14811b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 148207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 148307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 148407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 148507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 148607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 148707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 148807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 149207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1495d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1496eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1497eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_TEST, spid)) { 1498d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 149907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1502655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 150507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1506d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1507eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1508eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 1509d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 151107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 151566dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 1516655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1517494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1519655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 152007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 152107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 152207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 152607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 152707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 152807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1532f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1533f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1534eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1535d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1536eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1537d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1541f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1542f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1543f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1544f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1545f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1546f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1547494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1548494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1549494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1550b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1551b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1552b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 155307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1554655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 155507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1557ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1558ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 1559fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(filename.string(), &keyBlob, targetUid); 1560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1562494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1563d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1564eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1565eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 1566d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 156707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 156807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1570494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1571494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1572494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1573b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1574b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1575b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1578298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 157907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1581fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid); 158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 158407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1586298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1587298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1588494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1589d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1590eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1591eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_EXIST, spid)) { 1592d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1596494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1597494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1598494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1599b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1600b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1601b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 160207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1603655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 160407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1605655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 160607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 160707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1609298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1610298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1611494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1612d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1613eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1614eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SAW, spid)) { 1615d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 161607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 161707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1619494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1620494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1621494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1622b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1623b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1624b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1625655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1626655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1628655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 163107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1633655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1634655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 163507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1638655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1639655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1640655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1641655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1642655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1643655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1644655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1645655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1646655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1647655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 165007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 165107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 165207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 165307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 165507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 165607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 165707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 165807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 165907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 166407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 166507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1666298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1667298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 166807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1669d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1670eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1671eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_RESET, spid)) { 1672d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 167307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 167407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1676655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 167807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 168007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 168107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 168307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 168607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 168807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 169707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 169807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 169907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 170007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1705d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1706eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1707eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_PASSWORD, spid)) { 1708d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 170907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1714655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 171507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 171607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1717655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 171807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 172007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1721655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 172207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1725655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 172607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 172907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 173107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1732d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1733eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1734eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_LOCK, spid)) { 1735d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 173707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1739655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17409d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 174107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 174207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 174307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1745655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 174607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 174770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 174907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1750d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1751eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1752eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_UNLOCK, spid)) { 1753d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 175507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 175607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1757655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 17589d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 176007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 176107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 176307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 176407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 176570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 176670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 176707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1768d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1769eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1770eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_ZERO, spid)) { 1771d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 177207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 177307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 177470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1775655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 177670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 177770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 177896427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 177996427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1780d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1781eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1782eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1783d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 178407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 178507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 178670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1787494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1788494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1789494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1790b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1791b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1792b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1793655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1794f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1795f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 179607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 179707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 179907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 180007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 180107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 180217208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 180370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 180507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 180607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 180707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 180907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 181007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 181107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 181317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 181496427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 181596427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 181696427baf0094d50047049d329b0779c3c910402cKenny Root 181796427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 181896427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 181996427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 182096427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 182196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 182296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 182396427baf0094d50047049d329b0779c3c910402cKenny Root } 182496427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 182596427baf0094d50047049d329b0779c3c910402cKenny Root 182696427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 182796427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 182896427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 182996427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 183096427baf0094d50047049d329b0779c3c910402cKenny Root 183196427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 183296427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 183396427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 183496427baf0094d50047049d329b0779c3c910402cKenny Root 183596427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 183696427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 183796427baf0094d50047049d329b0779c3c910402cKenny Root 183896427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 183996427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 184096427baf0094d50047049d329b0779c3c910402cKenny Root } else { 184196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 184296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 184396427baf0094d50047049d329b0779c3c910402cKenny Root } 184496427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 184596427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 184696427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 184796427baf0094d50047049d329b0779c3c910402cKenny Root } 184896427baf0094d50047049d329b0779c3c910402cKenny Root 18491d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_DSA)) { 185017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 185117208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 185217208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 185317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 185417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 185517208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 185696427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 185796427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 185896427baf0094d50047049d329b0779c3c910402cKenny Root 185996427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 186096427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 186196427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 186296427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 186396427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 186496427baf0094d50047049d329b0779c3c910402cKenny Root } 186596427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 186696427baf0094d50047049d329b0779c3c910402cKenny Root 18671d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_EC)) { 186817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 186917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 187017208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 187117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 187217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 187396427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 187496427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 187596427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 187696427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 187796427baf0094d50047049d329b0779c3c910402cKenny Root 187896427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 187996427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 188096427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 188196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 188296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 188396427baf0094d50047049d329b0779c3c910402cKenny Root } 188496427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 188596427baf0094d50047049d329b0779c3c910402cKenny Root 188696427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 18876489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin ALOGI("invalid number of arguments: %zu", args->size()); 188896427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 188996427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 189096427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 189196427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 189296427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 189396427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 189496427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 189596427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 189696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 189796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 189896427baf0094d50047049d329b0779c3c910402cKenny Root } 189996427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 190096427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 190196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 190296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 190396427baf0094d50047049d329b0779c3c910402cKenny Root } 190496427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 190596427baf0094d50047049d329b0779c3c910402cKenny Root } 190696427baf0094d50047049d329b0779c3c910402cKenny Root } 190796427baf0094d50047049d329b0779c3c910402cKenny Root 190896427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 190996427baf0094d50047049d329b0779c3c910402cKenny Root } else { 191096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 191196427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 191296427baf0094d50047049d329b0779c3c910402cKenny Root } 191370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 191407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 191507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 191607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1918655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1919655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 192070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 192107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 192207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 192307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1924ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 192517208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 192617208e0de5a42722901d803118745cca25fd10c1Kenny Root 1927655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 192870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 192970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1930f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1931f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1932d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1933eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1934eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1935d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 193607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 193707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 193870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1939494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1940494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1941494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1942b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1943b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1944b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1945fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root State state = mKeyStore->getState(targetUid); 1946f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 194707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 194807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 194907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 195070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 195107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 195260898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 195370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1954fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->importKey(data, length, filename.string(), targetUid, flags); 195570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 195670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 195707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 195807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1959d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1960eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1961eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SIGN, spid)) { 1962d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 196307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 196407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 19659a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 196607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 196707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 196870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1969d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 197007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 197170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1972655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1973d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 197407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 197507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 197607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 197770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 197807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 197907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 198007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 198107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 198207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 198507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 198707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 199007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 199107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 199207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 199317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 199417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 199517208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 199617208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 199717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 199817208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 199917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 200007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 200107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 200207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 200307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 200670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 200770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 200907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 2010d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2011eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2012eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_VERIFY, spid)) { 2013d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 201407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2017655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20189d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 201907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 202007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 202107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 202270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 202307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 202407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 202507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 202670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2027655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2028494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 202907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 203007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 203107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 203270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 203407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 203507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 203607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 203770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 203907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 204007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 204107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 204207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 204307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 204570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 204617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 204717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 204817208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 204917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 205017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 205117208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 205217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 205307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 205407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 205507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 205607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 205870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 205970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 206207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 206807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 207007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 2072d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2073eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2074eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2075d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 207707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 208007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 208170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2082d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 208370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2084655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 208507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 208607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 209007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 209107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 209207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 209507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 209607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 209707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2099344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 210017208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 210117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 210217208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 210317208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 210417208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 210517208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 210617208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 210717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 210807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 210907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 211007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2111344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2113344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2114344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2115494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2116d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2117eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2118eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 2119d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2122344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2123494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2124494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2125494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2126b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2127b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2128b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 212907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2130fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 2131344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 213207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 2133655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 2134fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid); 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 213607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2138a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 213907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 2140a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 214107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 214207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 214307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 214507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 214617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 214707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 214807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 214907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 215307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 215707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 2158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 215907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 216007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2161d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2162eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2163eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2164d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 216507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 216607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 216707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2168655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21699d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 217007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 217107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 217207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 217307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 217407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2175655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 217607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2177655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 217807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 217907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 218007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2181655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 218207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2183a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 218407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 218507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2186d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2187eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2188eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2189d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 219007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 219107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2193655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21949d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 219507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 219607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 219707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 219907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2200655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 220107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2202655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 220307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 220407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 220507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2206655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 220907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2210d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2211eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2212eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2213d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 221436a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 221507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 221607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 221707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2218655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 221907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2220655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2221655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 222236a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 222407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2225655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 222607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2227655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 222836a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 222907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 223007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 223107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 223207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 223307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 223407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2235655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 223636a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 223707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 223807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 223936a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 224107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2242d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2243d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 22440225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2245eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2246eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DUPLICATE, spid)) { 2247d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 22480225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 22490225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22500225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2251655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22520225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2253d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 22540225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 22550225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22560225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2257d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2258d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2259d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2260d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 22610225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 22620225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22630225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2264d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2265d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2266d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22670225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2268d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2269d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2270d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2271d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2272d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2273d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22740225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2275d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2276d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2277d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2278d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22790225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22800225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2281d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2282655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2283d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2284d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2285fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid)); 22860225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2287655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2288655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 22890225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 22900225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22910225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2292d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2293655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2294fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root srcUid); 2295d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2296d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 22970225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2298d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2299fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, destUid); 23000225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23010225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 23021b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 23031b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 23048ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 23058ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2306fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int32_t clear_uid(int64_t targetUid64) { 2307fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root uid_t targetUid = static_cast<uid_t>(targetUid64); 2308a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2309eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2310eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_CLEAR_UID, spid)) { 2311a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2312a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2313a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2314a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2315fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (targetUid64 == -1) { 2316fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid = callingUid; 2317e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root } else if (!is_self_or_system(callingUid, targetUid)) { 2318e17c25459fc0f200134e10a1aaef12fa8f930f04Kenny Root ALOGW("permission denied for %d: clear_uid %d", callingUid, targetUid); 2319fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return ::PERMISSION_DENIED; 2320fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root } 2321fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root 2322a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2323a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2324655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2325a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2326a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2327a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2328fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 2329655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2330a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2331655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2332a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2333a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2334a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2335655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2336fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", targetUid); 2337a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2338a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2339a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2340a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2341a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2342655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2343655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2344a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2345a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2346a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2347655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2348655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2349655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2350655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2351655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2352655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2353655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2354655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2355a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2356655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2357a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2358fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, targetUid) 2359655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2360655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2361a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2362a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2363a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2364a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2365a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 236617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 2367a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2368a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2369655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2370a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2371a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2372a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2373a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23745f53124250025d3113c9c598a2f101330144b10cKenny Root if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) { 2375a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2376655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2377a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2378a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2379a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2380a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2381a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2382a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2383a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 238407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 23859d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 23869d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 23879d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 23889d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 23899d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 23909d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 23919d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 23929d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 23939d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 239507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 23961d448c074a86ef5d05a22fdf1358718976628a86Kenny Root bool isKeyTypeSupported(const keymaster_device_t* device, keymaster_keypair_t keyType) { 23971d448c074a86ef5d05a22fdf1358718976628a86Kenny Root const int32_t device_api = device->common.module->module_api_version; 23981d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) { 23991d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24001d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24011d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 24021d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 24031d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24041d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 24051d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 24061d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24071d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) { 24081d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24091d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24101d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24111d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 24121d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_DSA; 24131d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 24141d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_EC; 24151d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 24161d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 24171d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24181d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else { 24191d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return keyType == TYPE_RSA; 24201d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24211d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24221d448c074a86ef5d05a22fdf1358718976628a86Kenny Root 242307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 242407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 242507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 242607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 244270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 244370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 244470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 244570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 244670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 244770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 244870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2449eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ks_is_selinux_enabled = is_selinux_enabled(); 2450eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (ks_is_selinux_enabled) { 2451eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn union selinux_callback cb; 2452eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn cb.func_log = selinux_log_callback; 2453eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 2454eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getcon(&tctx) != 0) { 2455eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n"); 2456eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return -1; 2457eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2458eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 2459eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGI("SELinux: Keystore SELinux is disabled.\n"); 2460eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2461eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 246270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2463655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 246407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 246507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 246607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 246707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 246807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 246907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 247170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 247207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 247307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 247407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 247507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 247607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 247770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 247807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2481