keystore.cpp revision 70e3a86abd2c412d602a018967c01c177eb6cf4e
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> 26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h> 3770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 3870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/list.h> 3970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root//#define LOG_NDEBUG 0 41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define LOG_TAG "keystore" 42a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 43a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 44a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 45a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 46a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include "keystore.h" 47a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 48a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 49a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 50a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 51a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 52a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct Value { 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int length; 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE]; 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootclass ValueString { 6470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootpublic: 6570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString(const Value* orig) { 6670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root length = orig->length; 6770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value = new char[length + 1]; 6870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root memcpy(value, orig->value, length); 6970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value[length] = '\0'; 7070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 7170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 7270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ~ValueString() { 7370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete[] value; 7470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 7570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 7670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const char* c_str() const { 7770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return value; 7870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 7970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 8070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* release() { 8170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* ret = value; 8270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value = NULL; 8370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return ret; 8470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 8570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 8670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootprivate: 8770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* value; 8870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t length; 8970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}; 9070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 9170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 9270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 9370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 9470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 9570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 9670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 9770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 9870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 9970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 10370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 119a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 120a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 121a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 122a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 123a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 124a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 125a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key(char* out, const Value* key) { 127a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const uint8_t* in = key->value; 128a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int length = key->length; 129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 131a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 133a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 134a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 137a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 138a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const Value* key) { 14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 14470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 14570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return n + encode_key(out, key); 147a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 148a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1495187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic int decode_key(uint8_t* out, const char* in, int length) { 150a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = 0; i < length; ++i, ++in, ++out) { 151a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 154a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = (*in - '+') << 6; 155a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out |= (*++in - '0') & 0x3F; 156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --length; 157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return length; 161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 164a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size)); 167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (n == -1 || n == 0) { 168a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size-remaining; 169a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 171a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 172a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 173a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 177a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 178a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 179a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size)); 180a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (n == -1 || n == 0) { 181a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size-remaining; 182a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 183a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 184a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 187a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 192a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 193a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRandom != -1) { 194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 198a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 200a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRandom = ::open(randomDevice, O_RDONLY); 201a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRandom == -1) { 202a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 203a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 204a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 205a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2085187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 214a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * parts must be no more than VALUE_SIZE bytes. The first three bytes of the 221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * file are reserved for future use and are always set to zero. Fields other 222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t reserved[3]; 227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t encrypted[0]; 230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digested[0]; 232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 237a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength) { 239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 246a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 248a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 249a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 250a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 251a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2525187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 253a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 254a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 255a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2565187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 257a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 258a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 259a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2605187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 2615187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 2625187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 2635187818895c4c5f650a611c40531b1dff7764c18Kenny Root 2645187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 265a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 266a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 267a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 268a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) { 269a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 270a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 271a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 272a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 273a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 274a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 275a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 276a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 277a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 278a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 279a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 280a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 283a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 285a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 289a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 290a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 291a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root aes_key, vector, AES_ENCRYPT); 292a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 293a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.reserved, 0, sizeof(mBlob.reserved)); 294a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); 299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (out == -1) { 300a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR; 311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) { 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int in = open(filename, O_RDONLY); 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (in == -1) { 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) { 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.vector, AES_DECRYPT); 336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, computedDigest); 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 35970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct { 36070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint32_t uid; 36170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const uint8_t* keyName; 36270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 36370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode plist; 36470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t; 36570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore { 367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 36870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 3695187818895c4c5f650a611c40531b1dff7764c18Kenny Root : mEntropy(entropy) 37070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root , mDevice(device) 3715187818895c4c5f650a611c40531b1dff7764c18Kenny Root , mRetry(MAX_RETRY) 3725187818895c4c5f650a611c40531b1dff7764c18Kenny Root { 373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(MASTER_KEY_FILE, R_OK) == 0) { 374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 37870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 37970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_init(&mGrants); 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3825187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3865187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 39070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* getDevice() const { 39170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return mDevice; 39270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 39370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode initialize(Value* pw) { 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateMasterKey()) { 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = writeMasterKey(pw); 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode writeMasterKey(Value* pw) { 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt)); 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy); 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode readMasterKey(Value* pw) { 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int in = open(MASTER_KEY_FILE, O_RDONLY); 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (in == -1) { 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey); 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = writeMasterKey(pw); 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 471a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool reset() { 473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(file->d_name); 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4895187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool isEmpty() const { 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (isKeyFile(file->d_name)) { 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void lock() { 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode get(const char* filename, Blob* keyBlob) { 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyBlob->decryptBlob(filename, &mMasterKeyDecryption); 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode put(const char* filename, Blob* keyBlob) { 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy); 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 51970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root void addGrant(const char* filename, const Value* uidValue) { 52070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uid_t uid; 52170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (!convertToUid(uidValue, &uid)) { 52270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return; 52370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 52470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 52570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant = getGrant(filename, uid); 52670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant == NULL) { 52770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = new grant_t; 52870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant->uid = uid; 52970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant->keyName = reinterpret_cast<const uint8_t*>(strdup(filename)); 53070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_add_tail(&mGrants, &grant->plist); 53170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 53270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 53370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 53470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool removeGrant(const Value* keyValue, const Value* uidValue) { 53570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uid_t uid; 53670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (!convertToUid(uidValue, &uid)) { 53770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 53870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 53970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 54070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString keyString(keyValue); 54170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 54270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant = getGrant(keyString.c_str(), uid); 54370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant != NULL) { 54470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_remove(&grant->plist); 54570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete grant; 54670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return true; 54770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 54870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 54970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 55070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 55170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 55270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool hasGrant(const Value* keyValue, const uid_t uid) const { 55370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString keyString(keyValue); 55470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return getGrant(keyString.c_str(), uid) != NULL; 55570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 55670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const char* MASTER_KEY_FILE; 559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MAX_RETRY = 4; 563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const size_t SALT_SIZE = 16; 564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy* mEntropy; 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 56770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* mDevice; 56870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State mState; 570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t mRetry; 571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mSalt[SALT_SIZE]; 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyEncryption; 576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyDecryption; 577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 57870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode mGrants; 57970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setState(State state) { 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mState = state; 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRetry = MAX_RETRY; 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateSalt() { 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mEntropy->generate_random_data(mSalt, sizeof(mSalt)); 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateMasterKey() { 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setupMasterKeys() { 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_NO_ERROR); 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void clearMasterKeys() { 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mSalt, 0, sizeof(mSalt)); 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) { 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t saltSize; 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt != NULL) { 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = SALT_SIZE; 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) "keystore"; 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // sizeof = 9, not strlen = 8 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = sizeof("keystore"); 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key); 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static bool isKeyFile(const char* filename) { 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return ((strcmp(filename, MASTER_KEY_FILE) != 0) 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, ".") != 0) 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, "..") != 0)); 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 63270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 63370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t* getGrant(const char* keyName, uid_t uid) const { 63470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode *node; 63570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant; 63670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 63770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_for_each(node, &mGrants) { 63870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = node_to_item(node, grant_t, plist); 63970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 64070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root && !strcmp(reinterpret_cast<const char*>(grant->keyName), 64170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keyName)) { 64270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 64370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 64670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 64770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 64870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 64970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool convertToUid(const Value* uidValue, uid_t* uid) const { 65070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString uidString(uidValue); 65170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* end = NULL; 65270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *uid = strtol(uidString.c_str(), &end, 10); 65370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return *end == '\0'; 65470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey"; 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the protocol used in both requests and responses: 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * code [length_1 message_1 ... length_n message_n] end-of-file 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * where code is one byte long and lengths are unsigned 16-bit integers in 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * network order. Thus the maximum length of a message is 65535 bytes. */ 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_code(int sock, int8_t* code) { 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return recv(sock, code, 1, 0) == 1; 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_message(int sock, uint8_t* message, int length) { 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t bytes[2]; 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (recv(sock, &bytes[0], 1, 0) != 1 || 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root recv(sock, &bytes[1], 1, 0) != 1) { 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int offset = bytes[0] << 8 | bytes[1]; 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length < offset) { 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root length = offset; 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root offset = 0; 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (offset < length) { 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int n = recv(sock, &message[offset], length - offset, 0); 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (n <= 0) { 683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return -1; 684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root offset += n; 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return length; 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_end_of_file(int sock) { 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t byte; 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return recv(sock, &byte, 1, 0) == 0; 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic void send_code(int sock, int8_t code) { 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, &code, 1, 0); 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7005187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic void send_message(int sock, const uint8_t* message, int length) { 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint16_t bytes = htons(length); 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, &bytes, 2, 0); 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send(sock, message, length, 0); 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 70670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName, 70770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const uid_t uid) { 70870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 70970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 71070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 71170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ResponseCode responseCode = keyStore->get(filename, keyBlob); 71270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 71370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 71470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 71570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 71670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // If this is the Wifi or VPN user, they actually want system 71770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // UID keys. 71870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (uid == AID_WIFI || uid == AID_VPN) { 71970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, AID_SYSTEM, keyName); 72070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root responseCode = keyStore->get(filename, keyBlob); 72170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 72270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 72370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 72670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // They might be using a granted key. 72770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (!keyStore->hasGrant(keyName, uid)) { 72870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 72970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 73070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 73170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // It is a granted key. Try to load it. 73270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key(filename, keyName); 73370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return keyStore->get(filename, keyBlob); 73470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 73570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here are the actions. Each of them is a function without arguments. All 737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * information is defined in global variables, which are set properly before 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * performing an action. The number of parameters required by each action is 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * fixed and defined in a table. If the return value of an action is positive, 740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * it will be treated as a response code and transmitted to the client. Note 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that the lengths of parameters are checked when they are received, so 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * boundary checks on parameters are omitted. */ 743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0; 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7465187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode test(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (ResponseCode) keyStore->getState(); 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7505187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 75270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob keyBlob; 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob); 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (responseCode != NO_ERROR) { 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return responseCode; 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, NO_ERROR); 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_message(sock, keyBlob.getValue(), keyBlob.getLength()); 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7635187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode insert(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* val, 7645187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value*) { 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 76670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob keyBlob(val->value, val->length, NULL, 0); 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->put(filename, &keyBlob); 769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7715187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode del(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 77370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR; 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7775187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode exist(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 77970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(filename, R_OK) == -1) { 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7865187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode saw(KeyStore* keyStore, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) { 787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root char filename[NAME_MAX]; 79270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = encode_key_for_uid(filename, uid, keyPrefix); 793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, NO_ERROR); 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!strncmp(filename, file->d_name, n)) { 7985187818895c4c5f650a611c40531b1dff7764c18Kenny Root const char* p = &file->d_name[n]; 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p)); 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_message(sock, keyPrefix->value, keyPrefix->length); 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8075187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode reset(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->reset() ? NO_ERROR : SYSTEM_ERROR; 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the history. To improve the security, the parameters to generate the 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * master key has been changed. To make a seamless transition, we update the 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * file using the same password when the user unlock it for the first time. If 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * any thing goes wrong during the transition, the new file will not overwrite 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the old one. This avoids permanent damages of the existing data. */ 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8175187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode password(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value*, Value*) { 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (keyStore->getState()) { 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_UNINITIALIZED: { 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->initialize(pw); 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_NO_ERROR: { 824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // rewrite master key with new password. 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->writeMasterKey(pw); 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case STATE_LOCKED: { 828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // read master key, decrypt with password, initialize mMasterKey*. 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->readMasterKey(pw); 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8355187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode lock(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyStore->lock(); 837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return NO_ERROR; 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8405187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused, 8415187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value* unused2) { 8425187818895c4c5f650a611c40531b1dff7764c18Kenny Root return password(keyStore, sock, uid, pw, unused, unused2); 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8455187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode zero(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) { 846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR; 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 84970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode generate(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, 85070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 85170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 85270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data; 85370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 85470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 85570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 85670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 85770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 85870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 85970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 86170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->generate_keypair == NULL) { 86270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 86370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 86470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 86570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_rsa_keygen_params_t rsa_params; 86670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rsa_params.modulus_size = 2048; 86770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rsa_params.public_exponent = 0x10001; 86870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 86970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 87070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 87170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 87270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 87370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 87470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 87570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 87670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob(data, dataLength, NULL, 0); 87770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root free(data); 87870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 87970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return keyStore->put(filename, &keyBlob); 88070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 88170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 88270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode import(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* key, 88370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 88470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 88570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data; 88670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 88770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 88870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 88970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 89070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 89170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("No keymaster device!"); 89270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 89370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 89470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 89570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->import_keypair == NULL) { 89670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("Keymaster doesn't support import!"); 89770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 89870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 89970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 90070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->import_keypair(device, key->value, key->length, &data, &dataLength); 90170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 90270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("Error while importing keypair: %d", rc); 90370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 90470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 90570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 90670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 90770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 90870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob(data, dataLength, NULL, 0); 90970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root free(data); 91070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 91170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return keyStore->put(filename, &keyBlob); 91270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 91370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 91470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* 91570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * TODO: The abstraction between things stored in hardware and regular blobs 91670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * of data stored on the filesystem should be moved down to keystore itself. 91770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Unfortunately the Java code that calls this has naming conventions that it 91870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 91970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * data. 92070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * 92170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 92270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * "del_key" since the Java code doesn't really communicate what it's 92370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * intentions are. 92470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */ 92570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) { 92670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 92770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid); 92870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 92970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid); 93070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 93170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 93270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 93370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 93470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 93570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 93670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 93770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 93870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 93970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->get_keypair_public == NULL) { 94070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("device has no get_keypair_public implementation!"); 94170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 94270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 94370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 94470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data = NULL; 94570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 94670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 94770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data, 94870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root &dataLength); 94970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 95070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 95170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 95270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 95370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_code(sock, NO_ERROR); 95470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_message(sock, data, dataLength); 95570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root free(data); 95670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 95770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 95870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 95970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 96070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode del_key(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, 96170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 96270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 96370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 96470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 96570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ResponseCode responseCode = keyStore->get(filename, &keyBlob); 96670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 96770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 96870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 96970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 97070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 97170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 97270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 97370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 97470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 97570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->delete_keypair == NULL) { 97670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("device has no delete_keypair implementation!"); 97770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 97870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 97970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 98070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* data = NULL; 98170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t dataLength; 98270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 98370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc = device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength()); 98470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 98570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc ? SYSTEM_ERROR : NO_ERROR; 98670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 98770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 98870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode sign(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data, 98970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value*) { 99070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGV("sign %s from uid %d", ValueString(keyName).c_str(), uid); 99170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 99270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 99370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 99470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid); 99570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 99670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 99770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 99870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 99970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint8_t* signedData; 100070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t signedDataLength; 100170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 100270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 100370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 100470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 100570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 100670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 100770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->sign_data == NULL) { 100870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 100970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 101070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 101170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_rsa_sign_params_t params; 101270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.digest_type = DIGEST_NONE; 101370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.padding_type = PADDING_NONE; 101470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 101570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 101670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root data->value, data->length, &signedData, &signedDataLength); 101770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 101870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 101970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 102070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 102170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_code(sock, NO_ERROR); 102270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root send_message(sock, signedData, signedDataLength); 102370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR_RESPONSE_CODE_SENT; 102470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 102570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 102670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode verify(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data, 102770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value* signature) { 102870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Blob keyBlob; 102970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 103070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 103170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid); 103270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode != NO_ERROR) { 103370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 103470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 103570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 103670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const keymaster_device_t* device = keyStore->getDevice(); 103770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device == NULL) { 103870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 103970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 104070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 104170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (device->verify_data == NULL) { 104270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 104370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 104470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 104570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_rsa_sign_params_t params; 104670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.digest_type = DIGEST_NONE; 104770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root params.padding_type = PADDING_NONE; 104870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 104970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 105070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root data->value, data->length, signature->value, signature->length); 105170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 105270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return SYSTEM_ERROR; 105370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } else { 105470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR; 105570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 105670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 105770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 105870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode grant(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, 105970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value* granteeData, Value*) { 106070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 106170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 106270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (access(filename, R_OK) == -1) { 106370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 106470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 106570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 106670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keyStore->addGrant(filename, granteeData); 106770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NO_ERROR; 106870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 106970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 107070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode ungrant(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, 107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root Value* granteeData, Value*) { 107270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 107370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 107470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (access(filename, R_OK) == -1) { 107570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND; 107670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 107870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return keyStore->removeGrant(keyName, granteeData) ? NO_ERROR : KEY_NOT_FOUND; 107970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 108070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 108170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* Here are the permissions, actions, users, and the main function. */ 1082a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootenum perm { 10835187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_TEST = 1 << TEST, 10845187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_GET = 1 << GET, 10855187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_INSERT = 1 << INSERT, 10865187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_DELETE = 1 << DELETE, 10875187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_EXIST = 1 << EXIST, 10885187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_SAW = 1 << SAW, 10895187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_RESET = 1 << RESET, 10905187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_PASSWORD = 1 << PASSWORD, 10915187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_LOCK = 1 << LOCK, 10925187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_UNLOCK = 1 << UNLOCK, 10935187818895c4c5f650a611c40531b1dff7764c18Kenny Root P_ZERO = 1 << ZERO, 109470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_SIGN = 1 << SIGN, 109570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_VERIFY = 1 << VERIFY, 109670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_GRANT = 1 << GRANT, 1097a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1098a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10995187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic const int MAX_PARAM = 3; 1100a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1101a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const State STATE_ANY = (State) 0; 1102a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1103a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct action { 11045187818895c4c5f650a611c40531b1dff7764c18Kenny Root ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2, 11055187818895c4c5f650a611c40531b1dff7764c18Kenny Root Value* param3); 1106a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t code; 1107a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State state; 1108a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint32_t perm; 1109a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int lengths[MAX_PARAM]; 1110a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} actions[] = { 11115187818895c4c5f650a611c40531b1dff7764c18Kenny Root {test, CommandCodes[TEST], STATE_ANY, P_TEST, {0, 0, 0}}, 11125187818895c4c5f650a611c40531b1dff7764c18Kenny Root {get, CommandCodes[GET], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}}, 11135187818895c4c5f650a611c40531b1dff7764c18Kenny Root {insert, CommandCodes[INSERT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}}, 11145187818895c4c5f650a611c40531b1dff7764c18Kenny Root {del, CommandCodes[DELETE], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}}, 11155187818895c4c5f650a611c40531b1dff7764c18Kenny Root {exist, CommandCodes[EXIST], STATE_ANY, P_EXIST, {KEY_SIZE, 0, 0}}, 11165187818895c4c5f650a611c40531b1dff7764c18Kenny Root {saw, CommandCodes[SAW], STATE_ANY, P_SAW, {KEY_SIZE, 0, 0}}, 11175187818895c4c5f650a611c40531b1dff7764c18Kenny Root {reset, CommandCodes[RESET], STATE_ANY, P_RESET, {0, 0, 0}}, 11185187818895c4c5f650a611c40531b1dff7764c18Kenny Root {password, CommandCodes[PASSWORD], STATE_ANY, P_PASSWORD, {PASSWORD_SIZE, 0, 0}}, 11195187818895c4c5f650a611c40531b1dff7764c18Kenny Root {lock, CommandCodes[LOCK], STATE_NO_ERROR, P_LOCK, {0, 0, 0}}, 11205187818895c4c5f650a611c40531b1dff7764c18Kenny Root {unlock, CommandCodes[UNLOCK], STATE_LOCKED, P_UNLOCK, {PASSWORD_SIZE, 0, 0}}, 11215187818895c4c5f650a611c40531b1dff7764c18Kenny Root {zero, CommandCodes[ZERO], STATE_ANY, P_ZERO, {0, 0, 0}}, 112270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {generate, CommandCodes[GENERATE], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, 0, 0}}, 112370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {import, CommandCodes[IMPORT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}}, 112470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {sign, CommandCodes[SIGN], STATE_NO_ERROR, P_SIGN, {KEY_SIZE, VALUE_SIZE, 0}}, 112570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {verify, CommandCodes[VERIFY], STATE_NO_ERROR, P_VERIFY, {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}}, 112670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}}, 112770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {del_key, CommandCodes[DEL_KEY], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}}, 112870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {grant, CommandCodes[GRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}}, 112970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {ungrant, CommandCodes[UNGRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}}, 11305187818895c4c5f650a611c40531b1dff7764c18Kenny Root {NULL, 0, STATE_ANY, 0, {0, 0, 0}}, 1131a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1133a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct user { 1134a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid_t uid; 1135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid_t euid; 1136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint32_t perms; 1137a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} users[] = { 1138a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root {AID_SYSTEM, ~0, ~0}, 113970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {AID_VPN, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY }, 114070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {AID_WIFI, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY }, 11415187818895c4c5f650a611c40531b1dff7764c18Kenny Root {AID_ROOT, AID_SYSTEM, P_GET}, 114270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root {~0, ~0, P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | 114370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root P_SIGN | P_VERIFY}, 1144a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 1145a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1146a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) { 1147a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct user* user = users; 1148a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct action* action = actions; 1149a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int i; 1150a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1151a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (~user->uid && user->uid != uid) { 1152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++user; 1153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1154a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (action->code && action->code != code) { 1155a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++action; 1156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!action->code) { 1158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNDEFINED_ACTION; 1159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!(action->perm & user->perms)) { 1161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PERMISSION_DENIED; 1162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (action->state != STATE_ANY && action->state != keyStore->getState()) { 1164a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (ResponseCode) keyStore->getState(); 1165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (~user->euid) { 1167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uid = user->euid; 1168a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1169a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Value params[MAX_PARAM]; 1170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) { 1171a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root params[i].length = recv_message(sock, params[i].value, action->lengths[i]); 1172a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (params[i].length < 0) { 1173a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PROTOCOL_ERROR; 1174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!recv_end_of_file(sock)) { 1177a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return PROTOCOL_ERROR; 1178a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 11795187818895c4c5f650a611c40531b1dff7764c18Kenny Root return action->run(keyStore, sock, uid, ¶ms[0], ¶ms[1], ¶ms[2]); 1180a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1181a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1182a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 118370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root void* hardwareContext = NULL; 118470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int controlSocket = android_get_control_socket("keystore"); 1186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 1187a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 1188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 1191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 1192a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1193a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 1196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 1197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1198a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 119970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 120070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 120170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 120270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 120370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 120470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 120570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (listen(controlSocket, 3) == -1) { 1207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("listen: %s", strerror(errno)); 1208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root signal(SIGPIPE, SIG_IGN); 1212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 121370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 1214a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int sock; 1215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((sock = accept(controlSocket, NULL, 0)) != -1) { 1216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct timeval tv; 1217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root tv.tv_sec = 3; 1218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); 1219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); 1220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct ucred cred; 1222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root socklen_t size = sizeof(cred); 1223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size); 1224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (credResult != 0) { 1225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGW("getsockopt: %s", strerror(errno)); 1226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 1227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t request; 1228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (recv_code(sock, &request)) { 1229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State old_state = keyStore.getState(); 1230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = process(&keyStore, sock, cred.uid, request); 1231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR_RESPONSE_CODE_SENT) { 1232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = NO_ERROR; 1233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 1234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root send_code(sock, response); 1235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d", 1237a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root cred.uid, 1238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root request, response, 1239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root old_state, keyStore.getState(), 1240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root keyStore.getRetry()); 1241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(sock); 1244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("accept: %s", strerror(errno)); 124670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_release(dev); 124870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1249a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1250a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1251