keystore.cpp revision 822c3a99d930e9299e2fad2fb3e0ff91b119b95a
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; 44270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const uint8_t* keyName; 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; 62570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant->keyName = reinterpret_cast<const uint8_t*>(strdup(filename)); 62670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_add_tail(&mGrants, &grant->plist); 62770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 62870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 62970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 63070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool removeGrant(const Value* keyValue, const Value* uidValue) { 63170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uid_t uid; 63270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (!convertToUid(uidValue, &uid)) { 63370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 63470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 63570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 63670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString keyString(keyValue); 63770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 63870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant = getGrant(keyString.c_str(), uid); 63970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant != NULL) { 64070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_remove(&grant->plist); 64170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete grant; 64270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return true; 64370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 64570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 64670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 64870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool hasGrant(const Value* keyValue, const uid_t uid) const { 64970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString keyString(keyValue); 65070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return getGrant(keyString.c_str(), uid) != NULL; 65170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 65270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 653822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importKey(const Value* key, const char* filename) { 654822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 655822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 656822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 657822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 658822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 659822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 660822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 661822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 662822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 663822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root rc = mDevice->import_keypair(mDevice, key->value, key->length, &data, &dataLength); 664822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 665822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 666822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 667822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 668822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 669822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 670822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 671822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 672822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return put(filename, &keyBlob); 673822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 674822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const char* MASTER_KEY_FILE; 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MAX_RETRY = 4; 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const size_t SALT_SIZE = 16; 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy* mEntropy; 684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 68570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* mDevice; 68670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State mState; 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t mRetry; 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mSalt[SALT_SIZE]; 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyEncryption; 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyDecryption; 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 69670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode mGrants; 69770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setState(State state) { 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mState = state; 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRetry = MAX_RETRY; 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateSalt() { 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mEntropy->generate_random_data(mSalt, sizeof(mSalt)); 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateMasterKey() { 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setupMasterKeys() { 720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_NO_ERROR); 723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void clearMasterKeys() { 726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mSalt, 0, sizeof(mSalt)); 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 732a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) { 733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t saltSize; 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt != NULL) { 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = SALT_SIZE; 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) "keystore"; 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // sizeof = 9, not strlen = 8 740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = sizeof("keystore"); 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key); 743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static bool isKeyFile(const char* filename) { 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return ((strcmp(filename, MASTER_KEY_FILE) != 0) 747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, ".") != 0) 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, "..") != 0)); 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 75070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 75170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t* getGrant(const char* keyName, uid_t uid) const { 75270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode *node; 75370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant; 75470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 75570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_for_each(node, &mGrants) { 75670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = node_to_item(node, grant_t, plist); 75770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 75870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root && !strcmp(reinterpret_cast<const char*>(grant->keyName), 75970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keyName)) { 76070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 76170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 76270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 76370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 76470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 76570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 76670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 76770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool convertToUid(const Value* uidValue, uid_t* uid) const { 76870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString uidString(uidValue); 76970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* end = NULL; 77070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *uid = strtol(uidString.c_str(), &end, 10); 77170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return *end == '\0'; 77270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 773822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 774822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 775822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 776822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 777822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 778822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) { 779822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 780822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 781822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 782822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 783822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 784822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 785822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 786822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 787822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 788822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root importBlobAsKey(blob, filename); 789822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 790822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 791822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 792822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 793822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 794822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 795822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 796822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 797822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * */ 798822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 799822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 800822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 801822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root this->put(filename, blob); 802822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 803822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 804822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 805822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 806822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 807822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 808822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 809822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 810822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 811822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename) { 812822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 813822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 814822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 815822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 816822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 817822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 818822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 819822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 820822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 821822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 822822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 823822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 824822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 825822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 826822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 827822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 828822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 829822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 830822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 831822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 832822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Value pkcs8key; 833822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root pkcs8key.length = len; 834822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* tmp = pkcs8key.value; 835822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 836822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 837822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 838822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 839822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 840822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode rc = importKey(&pkcs8key, filename); 841822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 842822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 843822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 844822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 845822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return get(filename, blob, TYPE_KEY_PAIR); 846822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey"; 850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 851a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the protocol used in both requests and responses: 852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * code [length_1 message_1 ... length_n message_n] end-of-file 853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * where code is one byte long and lengths are unsigned 16-bit integers in 854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * network order. Thus the maximum length of a message is 65535 bytes. */ 855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_code(int sock, int8_t* code) { 857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return recv(sock, code, 1, 0) == 1; 858a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_message(int sock, uint8_t* message, int length) { 861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t bytes[2]; 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (recv(sock, &bytes[0], 1, 0) != 1 || 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root recv(sock, &bytes[1], 1, 0) != 1) { 864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int offset = bytes[0] << 8 | bytes[1]; 867a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length < offset) { 868a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 869a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root length = offset; 871a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root offset = 0; 872a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (offset < length) { 873a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int n = recv(sock, &message[offset], length - offset, 0); 874a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (n <= 0) { 875a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 876a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 877a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root offset += n; 878a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 879a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 880a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return length; 881a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 882a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 883a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_end_of_file(int sock) { 884a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t byte; 885a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return recv(sock, &byte, 1, 0) == 0; 886a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 887a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 888a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic void send_code(int sock, int8_t code) { 889a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, &code, 1, 0); 890a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 891a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8925187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic void send_message(int sock, const uint8_t* message, int length) { 893a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint16_t bytes = htons(length); 894a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, &bytes, 2, 0); 895a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, message, length, 0); 896a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 897a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 89870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName, 899822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uid_t uid, const BlobType type) { 90070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 90170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 90270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 903822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, keyBlob, type); 90470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 90570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 90670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 90770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 90870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // If this is the Wifi or VPN user, they actually want system 90970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // UID keys. 91070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (uid == AID_WIFI || uid == AID_VPN) { 91170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, AID_SYSTEM, keyName); 912822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root responseCode = keyStore->get(filename, keyBlob, type); 91370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 91470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 91570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 91670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 91770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 91870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // They might be using a granted key. 91970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (!keyStore->hasGrant(keyName, uid)) { 92070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 92170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 92270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 92370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // It is a granted key. Try to load it. 92470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key(filename, keyName); 925822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->get(filename, keyBlob, type); 92670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 92770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 928a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here are the actions. Each of them is a function without arguments. All 929a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * information is defined in global variables, which are set properly before 930a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * performing an action. The number of parameters required by each action is 931a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * fixed and defined in a table. If the return value of an action is positive, 932a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * it will be treated as a response code and transmitted to the client. Note 933a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that the lengths of parameters are checked when they are received, so 934a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * boundary checks on parameters are omitted. */ 935a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 936a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0; 937a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9385187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode test(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 939a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (ResponseCode) keyStore->getState(); 940a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 941a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9425187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 943a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 94470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 945a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob keyBlob; 946822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC); 947a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (responseCode != NO_ERROR) { 948a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return responseCode; 949a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 950a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, NO_ERROR); 951a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_message(sock, keyBlob.getValue(), keyBlob.getLength()); 952a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 953a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 954a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9555187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode insert(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* val, 9565187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value*) { 957a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 95870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 959822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(val->value, val->length, NULL, 0, TYPE_GENERIC); 960a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->put(filename, &keyBlob); 961a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 962a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9635187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode del(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 964a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 96570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 966822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob; 967822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC); 968822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (responseCode != NO_ERROR) { 969822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return responseCode; 970822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 971a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR; 972a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 973a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9745187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode exist(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 975a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 97670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 977a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(filename, R_OK) == -1) { 978a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 979a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 980a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 981a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 982a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9835187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode saw(KeyStore* keyStore, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) { 984a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 985a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 986a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 987a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 988a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 98970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = encode_key_for_uid(filename, uid, keyPrefix); 990a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, NO_ERROR); 991a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 992a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 993a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 994a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!strncmp(filename, file->d_name, n)) { 9955187818895c4c5f650a611c40531b1dff7764c18Kenny Root const char* p = &file->d_name[n]; 996a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p)); 997a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_message(sock, keyPrefix->value, keyPrefix->length); 998a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 999a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1000a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 1001a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 1002a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1003a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10045187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode reset(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 1005298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ResponseCode rc = keyStore->reset() ? NO_ERROR : SYSTEM_ERROR; 1006298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1007298e7b1b0f9116e2054d594d7538379d86585035Kenny Root const keymaster_device_t* device = keyStore->getDevice(); 1008298e7b1b0f9116e2054d594d7538379d86585035Kenny Root if (device == NULL) { 1009298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ALOGE("No keymaster device!"); 1010298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return SYSTEM_ERROR; 1011298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1012298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1013298e7b1b0f9116e2054d594d7538379d86585035Kenny Root if (device->delete_all == NULL) { 1014298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 1015298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return rc; 1016298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1017298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1018298e7b1b0f9116e2054d594d7538379d86585035Kenny Root if (device->delete_all(device)) { 1019298e7b1b0f9116e2054d594d7538379d86585035Kenny Root ALOGE("Problem calling keymaster's delete_all"); 1020298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return SYSTEM_ERROR; 1021298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1022298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1023298e7b1b0f9116e2054d594d7538379d86585035Kenny Root return rc; 1024a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1025a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1026a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the history. To improve the security, the parameters to generate the 1027a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * master key has been changed. To make a seamless transition, we update the 1028a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * file using the same password when the user unlock it for the first time. If 1029a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * any thing goes wrong during the transition, the new file will not overwrite 1030a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the old one. This avoids permanent damages of the existing data. */ 1031a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10325187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode password(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value*, Value*) { 1033a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (keyStore->getState()) { 1034a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_UNINITIALIZED: { 1035a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1036a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->initialize(pw); 1037a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1038a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_NO_ERROR: { 1039a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // rewrite master key with new password. 1040a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->writeMasterKey(pw); 1041a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_LOCKED: { 1043a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // read master key, decrypt with password, initialize mMasterKey*. 1044a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->readMasterKey(pw); 1045a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1046a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1047a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 1048a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1049a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10505187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode lock(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 1051a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyStore->lock(); 1052a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 1053a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1054a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10555187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused, 10565187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value* unused2) { 10575187818895c4c5f650a611c40531b1dff7764c18Kenny Root return password(keyStore, sock, uid, pw, unused, unused2); 1058a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1059a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10605187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode zero(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 1061a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR; 1062a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1063a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 106470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode generate(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, 106570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 106670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 106770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data; 106870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 106970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 107070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 107270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 107370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 107470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1075a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 107670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->generate_keypair == NULL) { 107770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 107870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 108070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_rsa_keygen_params_t rsa_params; 108170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rsa_params.modulus_size = 2048; 108270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rsa_params.public_exponent = 0x10001; 108370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 108470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 108570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 108670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 108770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 108870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 108970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 109070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1091822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 109270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root free(data); 109370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 109470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return keyStore->put(filename, &keyBlob); 109570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 109670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 109770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode import(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* key, 109870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 109970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 110070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 110170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 110270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->importKey(key, filename); 110470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 110570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 110670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* 110770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * TODO: The abstraction between things stored in hardware and regular blobs 110870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * of data stored on the filesystem should be moved down to keystore itself. 110970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Unfortunately the Java code that calls this has naming conventions that it 111070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 111170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * data. 111270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * 111370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 111470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * "del_key" since the Java code doesn't really communicate what it's 111570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * intentions are. 111670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */ 111770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 111870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 111970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid); 112070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1121822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR); 112270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 112370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 112470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 112570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 112670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 112770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 112870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 112970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 113170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->get_keypair_public == NULL) { 113270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("device has no get_keypair_public implementation!"); 113370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 113470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 113570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 113670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data = NULL; 113770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 113870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 113970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data, 114070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root &dataLength); 114170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 114270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 114370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 114470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 114570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_code(sock, NO_ERROR); 114670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_message(sock, data, dataLength); 114770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root free(data); 114870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 114970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 115070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 115170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 115270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode del_key(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, 115370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 115470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 115570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 115670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 1157822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_KEY_PAIR); 115870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 115970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 116070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 116170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 116270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 116370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 116470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 116570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 116670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 116770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->delete_keypair == NULL) { 116870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("device has no delete_keypair implementation!"); 116970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 117070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 117170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 117270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data = NULL; 117370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 117470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 117570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc = device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength()); 117670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 117770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc ? 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 122170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode verify(KeyStore* keyStore, int sock, 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 125370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode grant(KeyStore* keyStore, int sock, 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 126570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode ungrant(KeyStore* keyStore, int sock, 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 127370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return keyStore->removeGrant(keyName, granteeData) ? NO_ERROR : KEY_NOT_FOUND; 127470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 127570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* Here are the permissions, actions, users, and the main function. */ 1277a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootenum perm { 12785187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_TEST = 1 << TEST, 12795187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_GET = 1 << GET, 12805187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_INSERT = 1 << INSERT, 12815187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_DELETE = 1 << DELETE, 12825187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_EXIST = 1 << EXIST, 12835187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_SAW = 1 << SAW, 12845187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_RESET = 1 << RESET, 12855187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_PASSWORD = 1 << PASSWORD, 12865187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_LOCK = 1 << LOCK, 12875187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_UNLOCK = 1 << UNLOCK, 12885187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_ZERO = 1 << ZERO, 128970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_SIGN = 1 << SIGN, 129070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_VERIFY = 1 << VERIFY, 129170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_GRANT = 1 << GRANT, 1292a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1293a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 12945187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic const int MAX_PARAM = 3; 1295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const State STATE_ANY = (State) 0; 1297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct action { 12995187818895c4c5f650a611c40531b1dff7764c18Kenny Root ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2, 13005187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value* param3); 1301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t code; 1302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State state; 1303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint32_t perm; 1304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int lengths[MAX_PARAM]; 1305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} actions[] = { 13065187818895c4c5f650a611c40531b1dff7764c18Kenny Root {test, CommandCodes[TEST], STATE_ANY, P_TEST, {0, 0, 0}}, 13075187818895c4c5f650a611c40531b1dff7764c18Kenny Root {get, CommandCodes[GET], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}}, 13085187818895c4c5f650a611c40531b1dff7764c18Kenny Root {insert, CommandCodes[INSERT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}}, 13095187818895c4c5f650a611c40531b1dff7764c18Kenny Root {del, CommandCodes[DELETE], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}}, 13105187818895c4c5f650a611c40531b1dff7764c18Kenny Root {exist, CommandCodes[EXIST], STATE_ANY, P_EXIST, {KEY_SIZE, 0, 0}}, 13115187818895c4c5f650a611c40531b1dff7764c18Kenny Root {saw, CommandCodes[SAW], STATE_ANY, P_SAW, {KEY_SIZE, 0, 0}}, 13125187818895c4c5f650a611c40531b1dff7764c18Kenny Root {reset, CommandCodes[RESET], STATE_ANY, P_RESET, {0, 0, 0}}, 13135187818895c4c5f650a611c40531b1dff7764c18Kenny Root {password, CommandCodes[PASSWORD], STATE_ANY, P_PASSWORD, {PASSWORD_SIZE, 0, 0}}, 13145187818895c4c5f650a611c40531b1dff7764c18Kenny Root {lock, CommandCodes[LOCK], STATE_NO_ERROR, P_LOCK, {0, 0, 0}}, 13155187818895c4c5f650a611c40531b1dff7764c18Kenny Root {unlock, CommandCodes[UNLOCK], STATE_LOCKED, P_UNLOCK, {PASSWORD_SIZE, 0, 0}}, 13165187818895c4c5f650a611c40531b1dff7764c18Kenny Root {zero, CommandCodes[ZERO], STATE_ANY, P_ZERO, {0, 0, 0}}, 131770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {generate, CommandCodes[GENERATE], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, 0, 0}}, 131870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {import, CommandCodes[IMPORT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}}, 131970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {sign, CommandCodes[SIGN], STATE_NO_ERROR, P_SIGN, {KEY_SIZE, VALUE_SIZE, 0}}, 132070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {verify, CommandCodes[VERIFY], STATE_NO_ERROR, P_VERIFY, {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}}, 132170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}}, 132270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {del_key, CommandCodes[DEL_KEY], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}}, 132370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {grant, CommandCodes[GRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}}, 132470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {ungrant, CommandCodes[UNGRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}}, 13255187818895c4c5f650a611c40531b1dff7764c18Kenny Root {NULL, 0, STATE_ANY, 0, {0, 0, 0}}, 1326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct user { 1329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid_t uid; 1330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid_t euid; 1331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint32_t perms; 1332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} users[] = { 1333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root {AID_SYSTEM, ~0, ~0}, 133470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {AID_VPN, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY }, 133570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {AID_WIFI, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY }, 13365187818895c4c5f650a611c40531b1dff7764c18Kenny Root {AID_ROOT, AID_SYSTEM, P_GET}, 133770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {~0, ~0, P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | 133870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_SIGN | P_VERIFY}, 1339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) { 1342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct user* user = users; 1343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct action* action = actions; 1344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int i; 1345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (~user->uid && user->uid != uid) { 1347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++user; 1348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (action->code && action->code != code) { 1350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++action; 1351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!action->code) { 1353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNDEFINED_ACTION; 1354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!(action->perm & user->perms)) { 1356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PERMISSION_DENIED; 1357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (action->state != STATE_ANY && action->state != keyStore->getState()) { 1359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (ResponseCode) keyStore->getState(); 1360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (~user->euid) { 1362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid = user->euid; 1363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Value params[MAX_PARAM]; 1365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) { 1366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root params[i].length = recv_message(sock, params[i].value, action->lengths[i]); 1367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (params[i].length < 0) { 1368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PROTOCOL_ERROR; 1369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!recv_end_of_file(sock)) { 1372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PROTOCOL_ERROR; 1373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 13745187818895c4c5f650a611c40531b1dff7764c18Kenny Root return action->run(keyStore, sock, uid, ¶ms[0], ¶ms[1], ¶ms[2]); 1375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 137870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root void* hardwareContext = NULL; 137970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int controlSocket = android_get_control_socket("keystore"); 1381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 1382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 1383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 1386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 1387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 1391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 1392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 139470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 139570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 139670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 139770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 139870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 139970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 140070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (listen(controlSocket, 3) == -1) { 1402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("listen: %s", strerror(errno)); 1403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root signal(SIGPIPE, SIG_IGN); 1407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 140870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 1409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int sock; 1410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((sock = accept(controlSocket, NULL, 0)) != -1) { 1411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct timeval tv; 1412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root tv.tv_sec = 3; 1413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); 1414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); 1415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct ucred cred; 1417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root socklen_t size = sizeof(cred); 1418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size); 1419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (credResult != 0) { 1420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGW("getsockopt: %s", strerror(errno)); 1421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 1422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t request; 1423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (recv_code(sock, &request)) { 1424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State old_state = keyStore.getState(); 1425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = process(&keyStore, sock, cred.uid, request); 1426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR_RESPONSE_CODE_SENT) { 1427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = NO_ERROR; 1428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 1429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, response); 1430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d", 1432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root cred.uid, 1433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root request, response, 1434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root old_state, keyStore.getState(), 1435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyStore.getRetry()); 1436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(sock); 1439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("accept: %s", strerror(errno)); 144170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 144270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_release(dev); 144370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1446