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 17a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h> 18a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h> 19a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h> 20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h> 21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h> 22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h> 23a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h> 24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 26822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 34822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 37822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h> 4070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 41822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <utils/UniquePtr.h> 42822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/list.h> 4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root//#define LOG_NDEBUG 0 46a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define LOG_TAG "keystore" 47a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 48a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 49a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 50a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 51a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include "keystore.h" 52a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 63822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 64822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 65822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 66822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 67822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 68822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 69822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 70822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 71822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 72822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 73822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 74822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 75822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 77822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 78822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 79822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 81822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 82822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 86a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct Value { 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Value(const uint8_t* orig, int origLen) { 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root assert(origLen <= VALUE_SIZE); 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root memcpy(value, orig, origLen); 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root length = origLen; 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Value() { 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 96a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int length; 97a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE]; 98a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 99a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootclass ValueString { 10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootpublic: 10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString(const Value* orig) { 103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root assert(length <= VALUE_SIZE); 10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root length = orig->length; 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value = new char[length + 1]; 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root memcpy(value, orig->value, length); 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value[length] = '\0'; 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ~ValueString() { 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete[] value; 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const char* c_str() const { 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return value; 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* release() { 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* ret = value; 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value = NULL; 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return ret; 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootprivate: 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* value; 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t length; 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}; 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 13370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 13470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 13570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 13670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 13770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 13870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 14470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 14570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 14970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 15070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 15170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 15270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 15370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 15470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 15570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 15670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 16470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key(char* out, const Value* key) { 165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const uint8_t* in = key->value; 166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int length = key->length; 167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 168a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 169a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 171a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 172a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 173a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 17770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 17870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 17970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 18070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const Value* key) { 18170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 18270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 18370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 18470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return n + encode_key(out, key); 185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1875187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic int decode_key(uint8_t* out, const char* in, int length) { 188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = 0; i < length; ++i, ++in, ++out) { 189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 192a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = (*in - '+') << 6; 193a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out |= (*++in - '0') & 0x3F; 194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --length; 195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 198a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return length; 199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 200a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 201a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 202a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 203a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 204a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size)); 205a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (n == -1 || n == 0) { 206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size-remaining; 207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 214a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size)); 218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (n == -1 || n == 0) { 219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size-remaining; 220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRandom != -1) { 232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 237a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRandom = ::open(randomDevice, O_RDONLY); 239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRandom == -1) { 240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2465187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 248a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 249a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 250a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 251a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 252a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 253a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 254a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 255a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 256a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 257a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 258822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 259822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other 260a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 261a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 262a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 263822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 264822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 268822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 269822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 270822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 271822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 272822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 273822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 274822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 275822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 276822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 277a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 278822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 279822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 280822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t reserved; 281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 283822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 285822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 289a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstatic const uint8_t CurrentBlobVersion = 1; 297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength, BlobType type) { 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = CurrentBlobVersion; 308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3175187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3215187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3255187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 3265187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 3275187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 3285187818895c4c5f650a611c40531b1dff7764c18Kenny Root 3295187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 333822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 334822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 336822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) { 350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root aes_key, vector, AES_ENCRYPT); 373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 374822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.reserved = 0; 375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (out == -1) { 381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR; 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) { 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int in = open(filename, O_RDONLY); 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (in == -1) { 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) { 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.vector, AES_DECRYPT); 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, computedDigest); 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 44070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct { 44170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint32_t uid; 442a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom const uint8_t* filename; 44370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 44470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode plist; 44570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t; 44670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore { 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 44970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 4505187818895c4c5f650a611c40531b1dff7764c18Kenny Root : mEntropy(entropy) 45170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root , mDevice(device) 4525187818895c4c5f650a611c40531b1dff7764c18Kenny Root , mRetry(MAX_RETRY) 4535187818895c4c5f650a611c40531b1dff7764c18Kenny Root { 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(MASTER_KEY_FILE, R_OK) == 0) { 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 45970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 46070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_init(&mGrants); 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4635187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4675187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 47170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* getDevice() const { 47270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return mDevice; 47370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 47470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode initialize(Value* pw) { 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateMasterKey()) { 477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = writeMasterKey(pw); 480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode writeMasterKey(Value* pw) { 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy); 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode readMasterKey(Value* pw) { 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int in = open(MASTER_KEY_FILE, O_RDONLY); 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (in == -1) { 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey); 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = writeMasterKey(pw); 532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool reset() { 554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 555a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 556a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(file->d_name); 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5705187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool isEmpty() const { 571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (isKeyFile(file->d_name)) { 579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void lock() { 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 592822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) { 593822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption); 594822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 595822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 596822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 597822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 598822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 599822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version < CurrentBlobVersion) { 600822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root upgrade(filename, keyBlob, version, type); 601822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 602822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 603822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (keyBlob->getType() != type) { 604822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 605822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 606822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 607822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 608822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode put(const char* filename, Blob* keyBlob) { 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy); 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 61570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root void addGrant(const char* filename, const Value* uidValue) { 61670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uid_t uid; 61770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (!convertToUid(uidValue, &uid)) { 61870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return; 61970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 62070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 62170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant = getGrant(filename, uid); 62270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant == NULL) { 62370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = new grant_t; 62470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant->uid = uid; 625a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 62670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_add_tail(&mGrants, &grant->plist); 62770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 62870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 62970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 630a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool removeGrant(const char* filename, const Value* uidValue) { 63170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uid_t uid; 63270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (!convertToUid(uidValue, &uid)) { 63370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 63470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 63570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 636a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant_t *grant = getGrant(filename, uid); 63770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant != NULL) { 63870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_remove(&grant->plist); 63970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete grant; 64070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return true; 64170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 64370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 64470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 646a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 647a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 64870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 650822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importKey(const Value* key, const char* filename) { 651822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 652822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 653822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 654822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 655822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 656822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 657822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 658822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 659822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 660822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root rc = mDevice->import_keypair(mDevice, key->value, key->length, &data, &dataLength); 661822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 662822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 663822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 664822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 665822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 666822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 667822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 668822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 669822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return put(filename, &keyBlob); 670822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 671822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const char* MASTER_KEY_FILE; 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MAX_RETRY = 4; 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const size_t SALT_SIZE = 16; 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy* mEntropy; 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 68270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* mDevice; 68370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State mState; 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t mRetry; 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mSalt[SALT_SIZE]; 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyEncryption; 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyDecryption; 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 69370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode mGrants; 69470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setState(State state) { 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mState = state; 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRetry = MAX_RETRY; 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateSalt() { 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mEntropy->generate_random_data(mSalt, sizeof(mSalt)); 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateMasterKey() { 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setupMasterKeys() { 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_NO_ERROR); 720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void clearMasterKeys() { 723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mSalt, 0, sizeof(mSalt)); 725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) { 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t saltSize; 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt != NULL) { 732a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = SALT_SIZE; 733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) "keystore"; 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // sizeof = 9, not strlen = 8 737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = sizeof("keystore"); 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key); 740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static bool isKeyFile(const char* filename) { 743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return ((strcmp(filename, MASTER_KEY_FILE) != 0) 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, ".") != 0) 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, "..") != 0)); 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 74770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 748a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant_t* getGrant(const char* filename, uid_t uid) const { 74970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode *node; 75070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant; 75170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 75270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_for_each(node, &mGrants) { 75370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = node_to_item(node, grant_t, plist); 75470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 755a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom && !strcmp(reinterpret_cast<const char*>(grant->filename), 756a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom filename)) { 75770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 75870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 75970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 76070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 76170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 76270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 76370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 76470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool convertToUid(const Value* uidValue, uid_t* uid) const { 76570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString uidString(uidValue); 76670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* end = NULL; 76770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *uid = strtol(uidString.c_str(), &end, 10); 76870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return *end == '\0'; 76970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 770822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 771822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 772822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 773822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 774822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 775822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) { 776822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 777822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 778822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 779822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 780822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 781822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 782822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 783822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 784822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 785822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root importBlobAsKey(blob, filename); 786822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 787822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 788822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 789822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 790822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 791822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 792822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 793822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 794822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * */ 795822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 796822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 797822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 798822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root this->put(filename, blob); 799822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 800822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 801822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 802822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 803822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 804822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 805822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 806822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 807822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 808822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename) { 809822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 810822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 811822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 812822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 813822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 814822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 815822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 816822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 817822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 818822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 819822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 820822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 821822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 822822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 823822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 824822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 825822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 826822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 827822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 828822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 829822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Value pkcs8key; 830822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root pkcs8key.length = len; 831822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* tmp = pkcs8key.value; 832822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 833822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 834822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 835822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 836822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 837822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode rc = importKey(&pkcs8key, filename); 838822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 839822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 840822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 841822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 842822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return get(filename, blob, TYPE_KEY_PAIR); 843822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey"; 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the protocol used in both requests and responses: 849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * code [length_1 message_1 ... length_n message_n] end-of-file 850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * where code is one byte long and lengths are unsigned 16-bit integers in 851a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * network order. Thus the maximum length of a message is 65535 bytes. */ 852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_code(int sock, int8_t* code) { 854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return recv(sock, code, 1, 0) == 1; 855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_message(int sock, uint8_t* message, int length) { 858a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t bytes[2]; 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (recv(sock, &bytes[0], 1, 0) != 1 || 860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root recv(sock, &bytes[1], 1, 0) != 1) { 861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int offset = bytes[0] << 8 | bytes[1]; 864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length < offset) { 865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 867a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root length = offset; 868a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root offset = 0; 869a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (offset < length) { 870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int n = recv(sock, &message[offset], length - offset, 0); 871a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (n <= 0) { 872a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 873a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 874a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root offset += n; 875a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 876a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 877a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return length; 878a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 879a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 880a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_end_of_file(int sock) { 881a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t byte; 882a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return recv(sock, &byte, 1, 0) == 0; 883a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 884a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 885a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic void send_code(int sock, int8_t code) { 886a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, &code, 1, 0); 887a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 888a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8895187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic void send_message(int sock, const uint8_t* message, int length) { 890a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint16_t bytes = htons(length); 891a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, &bytes, 2, 0); 892a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, message, length, 0); 893a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 894a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 89570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName, 896822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uid_t uid, const BlobType type) { 89770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 89870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 89970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 900822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, keyBlob, type); 90170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 90270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 90370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 90470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 90570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // If this is the Wifi or VPN user, they actually want system 90670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // UID keys. 90770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (uid == AID_WIFI || uid == AID_VPN) { 90870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, AID_SYSTEM, keyName); 909822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root responseCode = keyStore->get(filename, keyBlob, type); 91070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 91170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 91270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 91370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 91470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 91570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // They might be using a granted key. 916a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom encode_key(filename, keyName); 917a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom if (!keyStore->hasGrant(filename, uid)) { 91870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 91970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 92070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 92170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // It is a granted key. Try to load it. 922822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->get(filename, keyBlob, type); 92370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 92470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 925a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here are the actions. Each of them is a function without arguments. All 926a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * information is defined in global variables, which are set properly before 927a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * performing an action. The number of parameters required by each action is 928a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * fixed and defined in a table. If the return value of an action is positive, 929a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * it will be treated as a response code and transmitted to the client. Note 930a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that the lengths of parameters are checked when they are received, so 931a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * boundary checks on parameters are omitted. */ 932a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 933a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0; 934a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 935da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode test(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) { 936a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (ResponseCode) keyStore->getState(); 937a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 938a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9395187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 940a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 94170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 942a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob keyBlob; 943822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC); 944a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (responseCode != NO_ERROR) { 945a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return responseCode; 946a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 947a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, NO_ERROR); 948a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_message(sock, keyBlob.getValue(), keyBlob.getLength()); 949a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 950a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 951a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 952da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode insert(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* val, 9535187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value*) { 954a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 95570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 956822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(val->value, val->length, NULL, 0, TYPE_GENERIC); 957a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->put(filename, &keyBlob); 958a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 959a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 960da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode del(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*, Value*) { 961a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 96270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 963822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob; 964822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC); 965822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (responseCode != NO_ERROR) { 966822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return responseCode; 967822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 968a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR; 969a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 970a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 971da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode exist(KeyStore*, int, uid_t uid, Value* keyName, Value*, Value*) { 972a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 97370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 974a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(filename, R_OK) == -1) { 975a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 976a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 977a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 978a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 979a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 980da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode saw(KeyStore*, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) { 981a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 982a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 983a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 984a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 985a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 98670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = encode_key_for_uid(filename, uid, keyPrefix); 987a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, NO_ERROR); 988a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 989a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 990a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 991a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!strncmp(filename, file->d_name, n)) { 9925187818895c4c5f650a611c40531b1dff7764c18Kenny Root const char* p = &file->d_name[n]; 993a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p)); 994a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_message(sock, keyPrefix->value, keyPrefix->length); 995a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 996a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 997a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 998a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 999a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1000a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1001da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode reset(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) { 1002298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ResponseCode rc = keyStore->reset() ? NO_ERROR : SYSTEM_ERROR; 1003298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1004298e7b1b0f9116e2054d594d7538379d86585035Kenny Root const keymaster_device_t* device = keyStore->getDevice(); 1005298e7b1b0f9116e2054d594d7538379d86585035Kenny Root if (device == NULL) { 1006298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ALOGE("No keymaster device!"); 1007298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return SYSTEM_ERROR; 1008298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1009298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1010298e7b1b0f9116e2054d594d7538379d86585035Kenny Root if (device->delete_all == NULL) { 1011298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 1012298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return rc; 1013298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1014298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1015298e7b1b0f9116e2054d594d7538379d86585035Kenny Root if (device->delete_all(device)) { 1016298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ALOGE("Problem calling keymaster's delete_all"); 1017298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return SYSTEM_ERROR; 1018298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1019298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1020298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return rc; 1021a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1022a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1023a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the history. To improve the security, the parameters to generate the 1024a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * master key has been changed. To make a seamless transition, we update the 1025a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * file using the same password when the user unlock it for the first time. If 1026a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * any thing goes wrong during the transition, the new file will not overwrite 1027a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the old one. This avoids permanent damages of the existing data. */ 1028a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1029da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode password(KeyStore* keyStore, int, uid_t, Value* pw, Value*, Value*) { 1030a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (keyStore->getState()) { 1031a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_UNINITIALIZED: { 1032a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1033a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->initialize(pw); 1034a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1035a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_NO_ERROR: { 1036a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // rewrite master key with new password. 1037a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->writeMasterKey(pw); 1038a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1039a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_LOCKED: { 1040a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // read master key, decrypt with password, initialize mMasterKey*. 1041a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->readMasterKey(pw); 1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1043a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1044a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 1045a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1046a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1047da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode lock(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) { 1048a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyStore->lock(); 1049a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 1050a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1051a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10525187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused, 10535187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value* unused2) { 10545187818895c4c5f650a611c40531b1dff7764c18Kenny Root return password(keyStore, sock, uid, pw, unused, unused2); 1055a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1056a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1057da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode zero(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) { 1058a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR; 1059a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1060a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1061da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode generate(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*, 106270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 106370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 106470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data; 106570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 106670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 106770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 106870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 106970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 107070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1072a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 107370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->generate_keypair == NULL) { 107470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 107570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 107770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_rsa_keygen_params_t rsa_params; 107870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rsa_params.modulus_size = 2048; 107970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rsa_params.public_exponent = 0x10001; 108070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 108170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 108270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 108370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 108470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 108570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 108670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 108770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1088822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 108970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root free(data); 109070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 109170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return keyStore->put(filename, &keyBlob); 109270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 109370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1094da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode import(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* key, 109570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 109670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 109770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 109870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 109970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->importKey(key, filename); 110170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 110270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 110370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* 110470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * TODO: The abstraction between things stored in hardware and regular blobs 110570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * of data stored on the filesystem should be moved down to keystore itself. 110670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Unfortunately the Java code that calls this has naming conventions that it 110770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 110870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * data. 110970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * 111070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 111170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * "del_key" since the Java code doesn't really communicate what it's 111270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * intentions are. 111370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */ 111470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 111570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 111670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid); 111770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1118822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR); 111970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 112070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 112170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 112270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 112370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 112470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 112570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 112670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 112770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 112870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->get_keypair_public == NULL) { 112970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("device has no get_keypair_public implementation!"); 113070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 113170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 113370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data = NULL; 113470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 113570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 113670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data, 113770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root &dataLength); 113870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 113970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 114070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 114170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 114270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_code(sock, NO_ERROR); 114370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_message(sock, data, dataLength); 114470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root free(data); 114570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 114670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 114770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 114870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1149da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode del_key(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*, 115070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 115170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 115270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 115370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 1154822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_KEY_PAIR); 115570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 115670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 115770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 115870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11599a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root ResponseCode rc = NO_ERROR; 11609a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 116170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 116270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 11639a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root rc = SYSTEM_ERROR; 11649a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } else { 11659a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root // A device doesn't have to implement delete_keypair. 11669a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root if (device->delete_keypair != NULL) { 11679a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 11689a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root rc = SYSTEM_ERROR; 11699a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } 11709a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } 117170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 117270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11739a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root if (rc != NO_ERROR) { 11749a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root return rc; 117570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 117670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11779a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR; 117870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 117970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 118070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode sign(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data, 118170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 118270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGV("sign %s from uid %d", ValueString(keyName).c_str(), uid); 118370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 118470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 118570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1186822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR); 118770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 118870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 118970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 119070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 119170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* signedData; 119270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t signedDataLength; 119370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 119470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 119570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 1196822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("no keymaster device; cannot sign"); 119770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 119870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 119970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 120070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->sign_data == NULL) { 1201822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("device doesn't implement signing"); 120270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 120370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 120470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 120570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_rsa_sign_params_t params; 120670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.digest_type = DIGEST_NONE; 120770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.padding_type = PADDING_NONE; 120870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 120970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 121070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root data->value, data->length, &signedData, &signedDataLength); 121170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 1212822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("device couldn't sign data"); 121370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 121470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 121570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 121670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_code(sock, NO_ERROR); 121770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_message(sock, signedData, signedDataLength); 121870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 121970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 122070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1221da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode verify(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* data, 122270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value* signature) { 122370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 122470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 122570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1226822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR); 122770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 122870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 122970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 123170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 123270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 123370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 123470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 123670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->verify_data == NULL) { 123770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 123870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_rsa_sign_params_t params; 124170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.digest_type = DIGEST_NONE; 124270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.padding_type = PADDING_NONE; 124370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 124570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root data->value, data->length, signature->value, signature->length); 124670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 124770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 124870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } else { 124970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR; 125070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 125170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 125270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1253da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode grant(KeyStore* keyStore, int, uid_t uid, Value* keyName, 125470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value* granteeData, Value*) { 125570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 125670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 125770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (access(filename, R_OK) == -1) { 125870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 125970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 126070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keyStore->addGrant(filename, granteeData); 126270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR; 126370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 126470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1265da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode ungrant(KeyStore* keyStore, int, uid_t uid, Value* keyName, 126670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value* granteeData, Value*) { 126770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 126870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 126970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (access(filename, R_OK) == -1) { 127070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 127170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 127270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1273a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return keyStore->removeGrant(filename, granteeData) ? NO_ERROR : KEY_NOT_FOUND; 127470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 127570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1276344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Rootstatic ResponseCode getmtime(KeyStore*, int sock, uid_t uid, Value* keyName, 1277344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root Value*, Value*) { 1278344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root char filename[NAME_MAX]; 1279344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root encode_key_for_uid(filename, uid, keyName); 1280344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root if (access(filename, R_OK) == -1) { 1281344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 1282344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1283344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1284344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root int fd = open(filename, O_NOFOLLOW, O_RDONLY); 1285344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root if (fd < 0) { 1286344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root return SYSTEM_ERROR; 1287344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1288344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1289344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root struct stat s; 1290344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root int ret = fstat(fd, &s); 1291344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root close(fd); 1292344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root if (ret == -1) { 1293344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root return SYSTEM_ERROR; 1294344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1295344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1296344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root uint8_t *data; 1297344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root int dataLength = asprintf(reinterpret_cast<char**>(&data), "%lu", s.st_mtime); 1298344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root if (dataLength < 0) { 1299344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root return SYSTEM_ERROR; 1300344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1301344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1302344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root send_code(sock, NO_ERROR); 1303344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root send_message(sock, data, dataLength); 1304344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root free(data); 1305344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1306344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 1307344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root} 1308344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 130970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* Here are the permissions, actions, users, and the main function. */ 1310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootenum perm { 13115187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_TEST = 1 << TEST, 13125187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_GET = 1 << GET, 13135187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_INSERT = 1 << INSERT, 13145187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_DELETE = 1 << DELETE, 13155187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_EXIST = 1 << EXIST, 13165187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_SAW = 1 << SAW, 13175187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_RESET = 1 << RESET, 13185187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_PASSWORD = 1 << PASSWORD, 13195187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_LOCK = 1 << LOCK, 13205187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_UNLOCK = 1 << UNLOCK, 13215187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_ZERO = 1 << ZERO, 132270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_SIGN = 1 << SIGN, 132370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_VERIFY = 1 << VERIFY, 132470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_GRANT = 1 << GRANT, 1325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 13275187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic const int MAX_PARAM = 3; 1328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const State STATE_ANY = (State) 0; 1330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct action { 13325187818895c4c5f650a611c40531b1dff7764c18Kenny Root ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2, 13335187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value* param3); 1334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t code; 1335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State state; 1336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint32_t perm; 1337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int lengths[MAX_PARAM]; 1338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} actions[] = { 13395187818895c4c5f650a611c40531b1dff7764c18Kenny Root {test, CommandCodes[TEST], STATE_ANY, P_TEST, {0, 0, 0}}, 13405187818895c4c5f650a611c40531b1dff7764c18Kenny Root {get, CommandCodes[GET], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}}, 13415187818895c4c5f650a611c40531b1dff7764c18Kenny Root {insert, CommandCodes[INSERT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}}, 13425187818895c4c5f650a611c40531b1dff7764c18Kenny Root {del, CommandCodes[DELETE], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}}, 13435187818895c4c5f650a611c40531b1dff7764c18Kenny Root {exist, CommandCodes[EXIST], STATE_ANY, P_EXIST, {KEY_SIZE, 0, 0}}, 13445187818895c4c5f650a611c40531b1dff7764c18Kenny Root {saw, CommandCodes[SAW], STATE_ANY, P_SAW, {KEY_SIZE, 0, 0}}, 13455187818895c4c5f650a611c40531b1dff7764c18Kenny Root {reset, CommandCodes[RESET], STATE_ANY, P_RESET, {0, 0, 0}}, 13465187818895c4c5f650a611c40531b1dff7764c18Kenny Root {password, CommandCodes[PASSWORD], STATE_ANY, P_PASSWORD, {PASSWORD_SIZE, 0, 0}}, 13475187818895c4c5f650a611c40531b1dff7764c18Kenny Root {lock, CommandCodes[LOCK], STATE_NO_ERROR, P_LOCK, {0, 0, 0}}, 13485187818895c4c5f650a611c40531b1dff7764c18Kenny Root {unlock, CommandCodes[UNLOCK], STATE_LOCKED, P_UNLOCK, {PASSWORD_SIZE, 0, 0}}, 13495187818895c4c5f650a611c40531b1dff7764c18Kenny Root {zero, CommandCodes[ZERO], STATE_ANY, P_ZERO, {0, 0, 0}}, 135070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {generate, CommandCodes[GENERATE], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, 0, 0}}, 135170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {import, CommandCodes[IMPORT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}}, 135270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {sign, CommandCodes[SIGN], STATE_NO_ERROR, P_SIGN, {KEY_SIZE, VALUE_SIZE, 0}}, 135370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {verify, CommandCodes[VERIFY], STATE_NO_ERROR, P_VERIFY, {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}}, 135470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}}, 135570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {del_key, CommandCodes[DEL_KEY], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}}, 135670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {grant, CommandCodes[GRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}}, 135770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {ungrant, CommandCodes[UNGRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}}, 1358344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root {getmtime, CommandCodes[GETMTIME], STATE_ANY, P_SAW, {KEY_SIZE, 0, 0}}, 13595187818895c4c5f650a611c40531b1dff7764c18Kenny Root {NULL, 0, STATE_ANY, 0, {0, 0, 0}}, 1360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct user { 1363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid_t uid; 1364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid_t euid; 1365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint32_t perms; 1366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} users[] = { 1367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root {AID_SYSTEM, ~0, ~0}, 136870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {AID_VPN, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY }, 136970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {AID_WIFI, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY }, 13705187818895c4c5f650a611c40531b1dff7764c18Kenny Root {AID_ROOT, AID_SYSTEM, P_GET}, 137170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {~0, ~0, P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | 137270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_SIGN | P_VERIFY}, 1373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) { 1376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct user* user = users; 1377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct action* action = actions; 1378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int i; 1379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1380e95ce35d10d6e0a7315a57f30d9c88d89880a4e1Amith Yamasani while (~user->uid && user->uid != (uid % AID_USER)) { 1381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++user; 1382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (action->code && action->code != code) { 1384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++action; 1385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!action->code) { 1387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNDEFINED_ACTION; 1388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!(action->perm & user->perms)) { 1390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PERMISSION_DENIED; 1391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (action->state != STATE_ANY && action->state != keyStore->getState()) { 1393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (ResponseCode) keyStore->getState(); 1394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (~user->euid) { 1396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid = user->euid; 1397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Value params[MAX_PARAM]; 1399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) { 1400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root params[i].length = recv_message(sock, params[i].value, action->lengths[i]); 1401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (params[i].length < 0) { 1402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PROTOCOL_ERROR; 1403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!recv_end_of_file(sock)) { 1406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PROTOCOL_ERROR; 1407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 14085187818895c4c5f650a611c40531b1dff7764c18Kenny Root return action->run(keyStore, sock, uid, ¶ms[0], ¶ms[1], ¶ms[2]); 1409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 1412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int controlSocket = android_get_control_socket("keystore"); 1413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 1414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 1415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 1418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 1419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 1423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 1424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 142670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 142770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 142870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 142970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 143070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 143170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 143270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (listen(controlSocket, 3) == -1) { 1434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("listen: %s", strerror(errno)); 1435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root signal(SIGPIPE, SIG_IGN); 1439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 144070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 1441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int sock; 1442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((sock = accept(controlSocket, NULL, 0)) != -1) { 1443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct timeval tv; 1444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root tv.tv_sec = 3; 1445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); 1446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); 1447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct ucred cred; 1449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root socklen_t size = sizeof(cred); 1450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size); 1451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (credResult != 0) { 1452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGW("getsockopt: %s", strerror(errno)); 1453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 1454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t request; 1455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (recv_code(sock, &request)) { 1456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State old_state = keyStore.getState(); 1457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = process(&keyStore, sock, cred.uid, request); 1458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR_RESPONSE_CODE_SENT) { 1459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = NO_ERROR; 1460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 1461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, response); 1462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d", 1464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root cred.uid, 1465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root request, response, 1466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root old_state, keyStore.getState(), 1467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyStore.getRetry()); 1468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(sock); 1471a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("accept: %s", strerror(errno)); 147370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 147470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_release(dev); 147570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1478