platform_system_security/keystore/blob.cpp

792 lines
27 KiB
C++
Raw Normal View History

/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "keystore"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <log/log.h>
#include "blob.h"
#include "keystore_utils.h"
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
#include <openssl/evp.h>
#include <openssl/rand.h>
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
#include <istream>
#include <ostream>
#include <streambuf>
#include <string>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
namespace {
constexpr size_t kGcmIvSizeBytes = 96 / 8;
#if defined(__clang__)
#define OPTNONE __attribute__((optnone))
#elif defined(__GNUC__)
#define OPTNONE __attribute__((optimize("O0")))
#else
#error Need a definition for OPTNONE
#endif
class ArrayEraser {
public:
ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
private:
volatile uint8_t* mArr;
size_t mSize;
};
/**
* Returns a EVP_CIPHER appropriate for the given key, based on the key's size.
*/
const EVP_CIPHER* getAesCipherForKey(const std::vector<uint8_t>& key) {
const EVP_CIPHER* cipher = EVP_aes_256_gcm();
if (key.size() == kAes128KeySizeBytes) {
cipher = EVP_aes_128_gcm();
}
return cipher;
}
/*
* Encrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
* 'iv' and write output to 'out' (which may be the same location as 'in') and 128-bit tag to
* 'tag'.
*/
ResponseCode AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len,
const std::vector<uint8_t>& key, const uint8_t* iv, uint8_t* tag) {
// There can be 128-bit and 256-bit keys
const EVP_CIPHER* cipher = getAesCipherForKey(key);
bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key.data(), iv);
EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
uint8_t* out_pos = out_tmp.get();
int out_len;
EVP_EncryptUpdate(ctx.get(), out_pos, &out_len, in, len);
out_pos += out_len;
EVP_EncryptFinal_ex(ctx.get(), out_pos, &out_len);
out_pos += out_len;
if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
ALOGD("Encrypted ciphertext is the wrong size, expected %zu, got %zd", len,
out_pos - out_tmp.get());
return ResponseCode::SYSTEM_ERROR;
}
std::copy(out_tmp.get(), out_pos, out);
EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kGcmTagLength, tag);
return ResponseCode::NO_ERROR;
}
/*
* Decrypt 'len' data at 'in' with AES-GCM, using 128-bit or 256-bit key at 'key', 96-bit IV at
* 'iv', checking 128-bit tag at 'tag' and writing plaintext to 'out'(which may be the same
* location as 'in').
*/
ResponseCode AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len,
const std::vector<uint8_t> key, const uint8_t* iv,
const uint8_t* tag) {
// There can be 128-bit and 256-bit keys
const EVP_CIPHER* cipher = getAesCipherForKey(key);
bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key.data(), iv);
EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kGcmTagLength, const_cast<uint8_t*>(tag));
std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
ArrayEraser out_eraser(out_tmp.get(), len);
uint8_t* out_pos = out_tmp.get();
int out_len;
EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
out_pos += out_len;
if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
ALOGE("Failed to decrypt blob; ciphertext or tag is likely corrupted");
return ResponseCode::VALUE_CORRUPTED;
}
out_pos += out_len;
if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
ALOGE("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
out_pos - out_tmp.get());
return ResponseCode::VALUE_CORRUPTED;
}
std::copy(out_tmp.get(), out_pos, out);
return ResponseCode::NO_ERROR;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
class ArrayStreamBuffer : public std::streambuf {
public:
template <typename T, size_t size> explicit ArrayStreamBuffer(const T (&data)[size]) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
static_assert(sizeof(T) == 1, "Array element size too large");
std::streambuf::char_type* d = const_cast<std::streambuf::char_type*>(
reinterpret_cast<const std::streambuf::char_type*>(&data[0]));
setg(d, d, d + size);
setp(d, d + size);
}
protected:
pos_type seekoff(off_type off, std::ios_base::seekdir dir,
std::ios_base::openmode which = std::ios_base::in |
std::ios_base::out) override {
bool in = which & std::ios_base::in;
bool out = which & std::ios_base::out;
if ((!in && !out) || (in && out && dir == std::ios_base::cur)) return -1;
std::streambuf::char_type* newPosPtr;
switch (dir) {
case std::ios_base::beg:
newPosPtr = pbase();
break;
case std::ios_base::cur:
// if dir == cur then in xor out due to
// if ((!in && !out) || (in && out && dir == std::ios_base::cur)) return -1; above
if (in)
newPosPtr = gptr();
else
newPosPtr = pptr();
break;
case std::ios_base::end:
// in and out bounds are the same and cannot change, so we can take either range
// regardless of the value of "which"
newPosPtr = epptr();
break;
}
newPosPtr += off;
if (newPosPtr < pbase() || newPosPtr > epptr()) return -1;
if (in) {
gbump(newPosPtr - gptr());
}
if (out) {
pbump(newPosPtr - pptr());
}
return newPosPtr - pbase();
}
};
} // namespace
Blob::Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
BlobType type) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob = std::make_unique<blobv3>();
memset(mBlob.get(), 0, sizeof(blobv3));
if (valueLength > kValueSize) {
valueLength = kValueSize;
ALOGW("Provided blob length too large");
}
if (infoLength + valueLength > kValueSize) {
infoLength = kValueSize - valueLength;
ALOGW("Provided info length too large");
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->length = valueLength;
memcpy(mBlob->value, value, valueLength);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->info = infoLength;
memcpy(mBlob->value + valueLength, info, infoLength);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->version = CURRENT_BLOB_VERSION;
mBlob->type = uint8_t(type);
if (type == TYPE_MASTER_KEY) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags = KEYSTORE_FLAG_ENCRYPTED;
} else {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags = KEYSTORE_FLAG_NONE;
}
}
Blob::Blob(blobv3 b) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob = std::make_unique<blobv3>(b);
}
Blob::Blob() {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (mBlob) *mBlob = {};
}
Blob::Blob(const Blob& rhs) {
if (rhs.mBlob) {
mBlob = std::make_unique<blobv3>(*rhs.mBlob);
}
}
Blob::Blob(Blob&& rhs) : mBlob(std::move(rhs.mBlob)) {}
Blob& Blob::operator=(const Blob& rhs) {
if (&rhs != this) {
if (mBlob) *mBlob = {};
if (rhs) {
mBlob = std::make_unique<blobv3>(*rhs.mBlob);
} else {
mBlob = {};
}
}
return *this;
}
Blob& Blob::operator=(Blob&& rhs) {
if (mBlob) *mBlob = {};
mBlob = std::move(rhs.mBlob);
return *this;
}
template <typename BlobType> static bool rawBlobIsEncrypted(const BlobType& blob) {
if (blob.version < 2) return true;
return blob.flags & (KEYSTORE_FLAG_ENCRYPTED | KEYSTORE_FLAG_SUPER_ENCRYPTED);
}
bool Blob::isEncrypted() const {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (mBlob->version < 2) {
return true;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
return mBlob->flags & KEYSTORE_FLAG_ENCRYPTED;
}
bool Blob::isSuperEncrypted() const {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
return mBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED;
}
bool Blob::isCriticalToDeviceEncryption() const {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
return mBlob->flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
}
inline uint8_t setFlag(uint8_t flags, bool set, KeyStoreFlag flag) {
return set ? (flags | flag) : (flags & ~flag);
}
void Blob::setEncrypted(bool encrypted) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags = setFlag(mBlob->flags, encrypted, KEYSTORE_FLAG_ENCRYPTED);
}
void Blob::setSuperEncrypted(bool superEncrypted) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags = setFlag(mBlob->flags, superEncrypted, KEYSTORE_FLAG_SUPER_ENCRYPTED);
}
void Blob::setCriticalToDeviceEncryption(bool critical) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags = setFlag(mBlob->flags, critical, KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
}
void Blob::setFallback(bool fallback) {
if (fallback) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags |= KEYSTORE_FLAG_FALLBACK;
} else {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags &= ~KEYSTORE_FLAG_FALLBACK;
}
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
static ResponseCode writeBlob(const std::string& filename, Blob blob, blobv3* rawBlob,
const std::vector<uint8_t>& aes_key, State state) {
ALOGV("writing blob %s", filename.c_str());
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
const size_t dataLength = rawBlob->length;
rawBlob->length = htonl(rawBlob->length);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (blob.isEncrypted() || blob.isSuperEncrypted()) {
if (state != STATE_NO_ERROR) {
ALOGD("couldn't insert encrypted blob while not unlocked");
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::LOCKED;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
memset(rawBlob->initialization_vector, 0, AES_BLOCK_SIZE);
if (!RAND_bytes(rawBlob->initialization_vector, kGcmIvSizeBytes)) {
ALOGW("Could not read random data for: %s", filename.c_str());
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::SYSTEM_ERROR;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
auto rc = AES_gcm_encrypt(rawBlob->value /* in */, rawBlob->value /* out */, dataLength,
aes_key, rawBlob->initialization_vector, rawBlob->aead_tag);
if (rc != ResponseCode::NO_ERROR) return rc;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
size_t fileLength = offsetof(blobv3, value) + dataLength + rawBlob->info;
char tmpFileName[] = ".tmpXXXXXX";
{
android::base::unique_fd out(TEMP_FAILURE_RETRY(mkstemp(tmpFileName)));
if (out < 0) {
LOG(ERROR) << "could not open temp file: " << tmpFileName
<< " for writing blob file: " << filename.c_str()
<< " because: " << strerror(errno);
return ResponseCode::SYSTEM_ERROR;
}
const size_t writtenBytes =
writeFully(out, reinterpret_cast<uint8_t*>(rawBlob), fileLength);
if (writtenBytes != fileLength) {
LOG(ERROR) << "blob not fully written " << writtenBytes << " != " << fileLength;
unlink(tmpFileName);
return ResponseCode::SYSTEM_ERROR;
}
}
if (rename(tmpFileName, filename.c_str()) == -1) {
LOG(ERROR) << "could not rename blob file to " << filename
<< " because: " << strerror(errno);
unlink(tmpFileName);
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::SYSTEM_ERROR;
}
fsyncDirectory(getContainingDirectory(filename));
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
return ResponseCode::NO_ERROR;
}
ResponseCode LockedKeyBlobEntry::writeBlobs(Blob keyBlob, Blob characteristicsBlob,
const std::vector<uint8_t>& aes_key,
State state) const {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (entry_ == nullptr) {
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::SYSTEM_ERROR;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
ResponseCode rc;
if (keyBlob) {
blobv3* rawBlob = keyBlob.mBlob.get();
rc = writeBlob(entry_->getKeyBlobPath(), std::move(keyBlob), rawBlob, aes_key, state);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (rc != ResponseCode::NO_ERROR) {
return rc;
}
}
if (characteristicsBlob) {
blobv3* rawBlob = characteristicsBlob.mBlob.get();
rc = writeBlob(entry_->getCharacteristicsBlobPath(), std::move(characteristicsBlob),
rawBlob, aes_key, state);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
}
return rc;
}
ResponseCode Blob::readBlob(const std::string& filename, const std::vector<uint8_t>& aes_key,
State state) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
ResponseCode rc;
ALOGV("reading blob %s", filename.c_str());
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
std::unique_ptr<blobv3> rawBlob = std::make_unique<blobv3>();
const int in = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY));
if (in < 0) {
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return (errno == ENOENT) ? ResponseCode::KEY_NOT_FOUND : ResponseCode::SYSTEM_ERROR;
}
// fileLength may be less than sizeof(mBlob)
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
const size_t fileLength = readFully(in, (uint8_t*)rawBlob.get(), sizeof(blobv3));
if (close(in) != 0) {
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::SYSTEM_ERROR;
}
if (fileLength == 0) {
LOG(ERROR) << __func__ << " VALUE_CORRUPTED file length == 0";
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::VALUE_CORRUPTED;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (rawBlobIsEncrypted(*rawBlob)) {
if (state == STATE_LOCKED) {
mBlob = std::move(rawBlob);
return ResponseCode::LOCKED;
}
if (state == STATE_UNINITIALIZED) return ResponseCode::UNINITIALIZED;
}
if (fileLength < offsetof(blobv3, value)) {
LOG(ERROR) << __func__ << " VALUE_CORRUPTED blob file too short: " << fileLength;
return ResponseCode::VALUE_CORRUPTED;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (rawBlob->version == 3) {
const ssize_t encryptedLength = ntohl(rawBlob->length);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (rawBlobIsEncrypted(*rawBlob)) {
rc = AES_gcm_decrypt(rawBlob->value /* in */, rawBlob->value /* out */, encryptedLength,
aes_key, rawBlob->initialization_vector, rawBlob->aead_tag);
if (rc != ResponseCode::NO_ERROR) {
// If the blob was superencrypted and decryption failed, it is
// almost certain that decryption is failing due to a user's
// changed master key.
if ((rawBlob->flags & KEYSTORE_FLAG_SUPER_ENCRYPTED) &&
(rc == ResponseCode::VALUE_CORRUPTED)) {
return ResponseCode::KEY_PERMANENTLY_INVALIDATED;
}
LOG(ERROR) << __func__ << " AES_gcm_decrypt returned: " << uint32_t(rc);
return rc;
}
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
} else if (rawBlob->version < 3) {
blobv2& v2blob = reinterpret_cast<blobv2&>(*rawBlob);
const size_t headerLength = offsetof(blobv2, encrypted);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
const ssize_t encryptedLength = fileLength - headerLength - v2blob.info;
if (encryptedLength < 0) {
LOG(ERROR) << __func__ << " VALUE_CORRUPTED v2blob file too short";
return ResponseCode::VALUE_CORRUPTED;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (rawBlobIsEncrypted(*rawBlob)) {
if (encryptedLength % AES_BLOCK_SIZE != 0) {
LOG(ERROR) << __func__
<< " VALUE_CORRUPTED encrypted length is not a multiple"
" of the AES block size";
return ResponseCode::VALUE_CORRUPTED;
}
AES_KEY key;
AES_set_decrypt_key(aes_key.data(), kAesKeySize * 8, &key);
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
AES_cbc_encrypt(v2blob.encrypted, v2blob.encrypted, encryptedLength, &key,
v2blob.vector, AES_DECRYPT);
key = {}; // clear key
uint8_t computedDigest[MD5_DIGEST_LENGTH];
ssize_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
MD5(v2blob.digested, digestedLength, computedDigest);
if (memcmp(v2blob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
LOG(ERROR) << __func__ << " v2blob MD5 digest mismatch";
return ResponseCode::VALUE_CORRUPTED;
}
}
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
const ssize_t maxValueLength = fileLength - offsetof(blobv3, value) - rawBlob->info;
rawBlob->length = ntohl(rawBlob->length);
if (rawBlob->length < 0 || rawBlob->length > maxValueLength ||
rawBlob->length + rawBlob->info + AES_BLOCK_SIZE >
static_cast<ssize_t>(sizeof(rawBlob->value))) {
LOG(ERROR) << __func__ << " raw blob length is out of bounds";
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::VALUE_CORRUPTED;
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (rawBlob->info != 0 && rawBlob->version < 3) {
// move info from after padding to after data
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
memmove(rawBlob->value + rawBlob->length, rawBlob->value + maxValueLength, rawBlob->info);
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob = std::move(rawBlob);
Port to binderized keymaster HAL This patch ports keystore to the HIDL based binderized keymaster HAL. Keystore has no more dependencies on legacy keymaster headers, and therefore data structures, constant declarations, or enums. All keymaster related data structures and enums used by keystore are the once defined by the HIDL based keymaster HAL definition. In the process of porting, keystore underwent some changes: * Keystore got a new implementation of AuthorizationSet that is fully based on the new HIDL data structures. Key parameters are now either organised as AuthorizationSets or hidl_vec<KeyParameter>. (Formerly, this was a mixture of keymaster's AuthorizationSet, std::vec<keymaster_key_param_t>, and keymaster_key_param_set_t.) The former is used for memory management and provides algorithms for assembling, joining, and subtracting sets of parameters. The latter is used as wire format for the HAL IPC; it can wrap the memory owned by an AuthorizationSet for this purpose. The AuthorizationSet is accompanied by a new implementation of type safe functions for creating and accessing tagged key parameters, Authorizations (keystore/keymaster_tags.h). * A new type (KSSReturnCode) was introduced that wraps keystore service response codes. Keystore has two sets of error codes. ErrorCode errors are less than 0 and use 0 as success value. ResponseCode errors are greater than zero and use 1 as success value. This patch changes ResponseCode to be an enum class so that is no longer assignable to int without a cast. The new return type can only be initialized by ResponseCode or ErrorCode and when accessed as int32_t, which happens on serialization when the response is send to a client, the success values are coalesced onto 1 as expected by the clients. KSSreturnCode is also comparable to ResponseCode and ErrorCode, and the predicate isOk() returns true if it was initialized with either ErrorCode::OK (0) or ReponseCode::NO_ERROR (1). * A bug was fixed, that caused the keystore verify function to return success, regardless of the input, internal errors, or lack of permissions. * The marshalling code in IKeystoreService.cpp was rewritten. For data structures that are known to keymaster, the client facing side of keystore uses HIDL based data structures as (target) source for (un)marshaling to avoid further conversion. hidl_vecs are used to wrap parcel memory without copying and taking ownership where possible. * Explicit use of malloc is reduced (malloc was required by the C nature of the old HAL). The new implementations avoid explicit use of malloc/new and waive the use of pointers for return values. Instead, functions return by value objects that take ownership of secondary memory allocations where required. Test: runtest --path=cts/tests/tests/keystore/src/android/keystore/cts Bug: 32020919 Change-Id: I59d3a0f4a6bdf6bb3bbf791ad8827c463effa286
2016-10-13 19:43:45 +02:00
return ResponseCode::NO_ERROR;
}
std::tuple<ResponseCode, Blob, Blob>
LockedKeyBlobEntry::readBlobs(const std::vector<uint8_t>& aes_key, State state) const {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
std::tuple<ResponseCode, Blob, Blob> result;
auto& [rc, keyBlob, characteristicsBlob] = result;
if (entry_ == nullptr) return rc = ResponseCode::SYSTEM_ERROR, result;
rc = keyBlob.readBlob(entry_->getKeyBlobPath(), aes_key, state);
if (rc != ResponseCode::NO_ERROR && rc != ResponseCode::UNINITIALIZED) {
return result;
}
if (entry_->hasCharacteristicsBlob()) {
characteristicsBlob.readBlob(entry_->getCharacteristicsBlobPath(), aes_key, state);
}
return result;
}
ResponseCode LockedKeyBlobEntry::deleteBlobs() const {
if (entry_ == nullptr) return ResponseCode::NO_ERROR;
// always try to delete both
ResponseCode rc1 = (unlink(entry_->getKeyBlobPath().c_str()) && errno != ENOENT)
? ResponseCode::SYSTEM_ERROR
: ResponseCode::NO_ERROR;
if (rc1 != ResponseCode::NO_ERROR) {
ALOGW("Failed to delete key blob file \"%s\"", entry_->getKeyBlobPath().c_str());
}
ResponseCode rc2 = (unlink(entry_->getCharacteristicsBlobPath().c_str()) && errno != ENOENT)
? ResponseCode::SYSTEM_ERROR
: ResponseCode::NO_ERROR;
if (rc2 != ResponseCode::NO_ERROR) {
ALOGW("Failed to delete key characteristics file \"%s\"",
entry_->getCharacteristicsBlobPath().c_str());
}
// then report the first error that occured
if (rc1 != ResponseCode::NO_ERROR) return rc1;
return rc2;
}
keystore::SecurityLevel Blob::getSecurityLevel() const {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
return keystore::flagsToSecurityLevel(mBlob->flags);
}
void Blob::setSecurityLevel(keystore::SecurityLevel secLevel) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
mBlob->flags &= ~(KEYSTORE_FLAG_FALLBACK | KEYSTORE_FLAG_STRONGBOX);
mBlob->flags |= keystore::securityLevelToFlags(secLevel);
}
std::tuple<bool, keystore::AuthorizationSet, keystore::AuthorizationSet>
Blob::getKeyCharacteristics() const {
std::tuple<bool, keystore::AuthorizationSet, keystore::AuthorizationSet> result;
auto& [success, hwEnforced, swEnforced] = result;
success = false;
ArrayStreamBuffer buf(mBlob->value);
std::istream in(&buf);
// only the characteristics cache has both sets
if (getType() == TYPE_KEY_CHARACTERISTICS_CACHE) {
hwEnforced.Deserialize(&in);
} else if (getType() != TYPE_KEY_CHARACTERISTICS) {
// if its not the cache and not the legacy characteristics file we have no business
// here
return result;
}
swEnforced.Deserialize(&in);
success = !in.bad();
return result;
}
bool Blob::putKeyCharacteristics(const keystore::AuthorizationSet& hwEnforced,
const keystore::AuthorizationSet& swEnforced) {
if (!mBlob) mBlob = std::make_unique<blobv3>();
mBlob->version = CURRENT_BLOB_VERSION;
ArrayStreamBuffer buf(mBlob->value);
std::ostream out(&buf);
hwEnforced.Serialize(&out);
swEnforced.Serialize(&out);
if (out.bad()) return false;
setType(TYPE_KEY_CHARACTERISTICS_CACHE);
mBlob->length = out.tellp();
return true;
}
void LockedKeyBlobEntry::put(const KeyBlobEntry& entry) {
std::unique_lock<std::mutex> lock(locked_blobs_mutex_);
locked_blobs_.erase(entry);
lock.unlock();
locked_blobs_mutex_cond_var_.notify_all();
}
LockedKeyBlobEntry::~LockedKeyBlobEntry() {
if (entry_ != nullptr) put(*entry_);
}
LockedKeyBlobEntry LockedKeyBlobEntry::get(KeyBlobEntry entry) {
std::unique_lock<std::mutex> lock(locked_blobs_mutex_);
locked_blobs_mutex_cond_var_.wait(
lock, [&] { return locked_blobs_.find(entry) == locked_blobs_.end(); });
auto [iterator, success] = locked_blobs_.insert(std::move(entry));
if (!success) return {};
return LockedKeyBlobEntry(*iterator);
}
std::set<KeyBlobEntry> LockedKeyBlobEntry::locked_blobs_;
std::mutex LockedKeyBlobEntry::locked_blobs_mutex_;
std::condition_variable LockedKeyBlobEntry::locked_blobs_mutex_cond_var_;
/* Here is the encoding of key names. This is necessary in order to allow arbitrary
* characters in key names. Characters in [0-~] are not encoded. Others are encoded
* into two bytes. The first byte is one of [+-.] which represents the first
* two bits of the character. The second byte encodes the rest of the bits into
* [0-o]. Therefore in the worst case the length of a key gets doubled. Note
* that Base64 cannot be used here due to the need of prefix match on keys. */
std::string encodeKeyName(const std::string& keyName) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
std::string encodedName;
encodedName.reserve(keyName.size() * 2);
auto in = keyName.begin();
while (in != keyName.end()) {
// Input character needs to be encoded.
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
if (*in < '0' || *in > '~') {
// Encode the two most-significant bits of the input char in the first
// output character, by counting up from 43 ('+').
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
encodedName.append(1, '+' + (uint8_t(*in) >> 6));
// Encode the six least-significant bits of the input char in the second
// output character, by counting up from 48 ('0').
// This is safe because the maximum value is 112, which is the
// character 'p'.
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
encodedName.append(1, '0' + (*in & 0x3F));
} else {
// No need to encode input char - append as-is.
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
encodedName.append(1, *in);
}
++in;
}
return encodedName;
}
std::string decodeKeyName(const std::string& encodedName) {
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
std::string decodedName;
decodedName.reserve(encodedName.size());
auto in = encodedName.begin();
bool multichar = false;
char c;
while (in != encodedName.end()) {
if (multichar) {
// Second part of a multi-character encoding. Turn off the multichar
// flag and set the six least-significant bits of c to the value originally
// encoded by counting up from '0'.
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
multichar = false;
decodedName.append(1, c | (uint8_t(*in) - '0'));
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
} else if (*in >= '+' && *in <= '.') {
// First part of a multi-character encoding. Set the multichar flag
// and set the two most-significant bits of c to be the two bits originally
// encoded by counting up from '+'.
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
multichar = true;
c = (*in - '+') << 6;
} else {
// Regular character, append as-is.
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
decodedName.append(1, *in);
}
++in;
}
// mulitchars at the end get truncated
return decodedName;
}
std::string KeyBlobEntry::getKeyBlobBaseName() const {
std::stringstream s;
if (masterkey_) {
s << alias_;
} else {
s << uid_ << "_" << encodeKeyName(alias_);
}
return s.str();
}
std::string KeyBlobEntry::getKeyBlobPath() const {
std::stringstream s;
if (masterkey_) {
s << user_dir_ << "/" << alias_;
} else {
s << user_dir_ << "/" << uid_ << "_" << encodeKeyName(alias_);
}
return s.str();
}
std::string KeyBlobEntry::getCharacteristicsBlobBaseName() const {
std::stringstream s;
if (!masterkey_) s << "." << uid_ << "_chr_" << encodeKeyName(alias_);
return s.str();
}
std::string KeyBlobEntry::getCharacteristicsBlobPath() const {
std::stringstream s;
if (!masterkey_)
s << user_dir_ << "/"
<< "." << uid_ << "_chr_" << encodeKeyName(alias_);
return s.str();
}
bool KeyBlobEntry::hasKeyBlob() const {
int trys = 3;
while (trys--) {
if (!access(getKeyBlobPath().c_str(), R_OK | W_OK)) return true;
if (errno == ENOENT) return false;
LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
<< " while checking for key blob";
if (errno != EAGAIN) break;
}
return false;
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
}
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
bool KeyBlobEntry::hasCharacteristicsBlob() const {
int trys = 3;
while (trys--) {
if (!access(getCharacteristicsBlobPath().c_str(), R_OK | W_OK)) return true;
if (errno == ENOENT) return false;
LOG(WARNING) << "access encountered " << strerror(errno) << " (" << errno << ")"
<< " while checking for key characteristics blob";
if (errno != EAGAIN) break;
}
return false;
Multithreaded Keystore This patch transitions keystore a threading model with one dispatcher thread and one worker thread per keymaster instance, i.e. fallback, TEE, Strongbox (if available). Singleton objects, such as the user state database, the enforcement policy, and grant database have been moved to KeyStore and were made concurrency safe. Other noteworthy changes in this patch: * Cached key characteristics. The key characteristics file used to hold a limited set of parameters used generate or import the key. This patch introduces a new blob type that holds full characteristics as returned by generate, import, or getKeyCharacteristics, with the original parameters mixed into the software enforced list. When keystore encounters a lagacy characteristics file it will grab the characteristics from keymaster, merge them with the cached parameters, and update the cache file to the new format. If keystore encounters the new cache no call to keymaster will be made for retrieving the key characteristics. * Changed semantic of list. The list call takes a prefix used for filtering key entries. By the old semantic, list would return a list of aliases stripped of the given prefix. By the new semantic list always returns a filtered list of full alias string. Callers may strip prefixes if they are so inclined. * Entertain per keymaster instance operation maps. With the introduction of Strongbox keystore had to deal with multiple keymaster instances. But until now it would entertain a single operations map. Keystore also enforces the invariant that no more than 15 operation slots are used so there is always a free slot available for vold. With a single operation map, this means no more than 15 slots can ever be used although with TEE and Strongbox there are a total of 32 slots. With strongbox implementation that have significantly fewer slots we see another effect of the single operation map. If a slot needs to be freed on Stronbox but the oldest operations are on TEE, the latter will be unnecessarily pruned before a Strongbox slot is freed up. With this patch each keymaster instance has its own operation map and pruning is performed on a per keymaster instance basis. * Introduce KeyBlobEntries which are independent from files. To allow concurrent access to the key blob data base, entries can be individually locked so that operations on entries become atomic. LockedKeyBlobEntries are move only objects that track ownership of an Entry on the stack or in functor object representing keymaster worker requests. Entries must only be locked by the dispatcher Thread. Worker threads can only be granted access to a LockedKeyBlobEntry by the dispatcher thread. This allows the dispatcher thread to execute a barrier that waits until all locks held by workers have been relinquished to perform blob database maintenance operations, e.g., clearing a uid of all entries. * Verification tokens are now acquired asynchronously. When a begin operation requires a verification token a request is submitted to the other keymaster worker while the begin call returns. When the operation commences with update or finish, we block until the verification token becomes available. As of this patch the keystore IPC interface is still synchronous. That is, the dispatcher thread dispatches a request to a worker and then waits until the worker has finished. In a followup patch the IPC interface shall be made asynchronous so that multiple requests may be in flight. Test: Ran full CTS test suite atest android.keystore.cts Bug: 111443219 Bug: 110495056 Change-Id: I305e28d784295a0095a34810d83202f7423498bd
2018-10-08 16:15:09 +02:00
}
static std::tuple<bool, uid_t, std::string> filename2UidAlias(const std::string& filepath) {
std::tuple<bool, uid_t, std::string> result;
auto& [success, uid, alias] = result;
success = false;
auto filenamebase = filepath.find_last_of('/');
std::string filename =
filenamebase == std::string::npos ? filepath : filepath.substr(filenamebase + 1);
if (filename[0] == '.') return result;
auto sep = filename.find('_');
if (sep == std::string::npos) return result;
std::stringstream s(filename.substr(0, sep));
s >> uid;
if (!s) return result;
alias = decodeKeyName(filename.substr(sep + 1));
success = true;
return result;
}
std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>>
LockedKeyBlobEntry::list(const std::string& user_dir,
std::function<bool(uid_t, const std::string&)> filter) {
std::list<LockedKeyBlobEntry> matches;
// This is a fence against any concurrent database accesses during database iteration.
// Only the keystore thread can lock entries. So it cannot be starved
// by workers grabbing new individual locks. We just wait here until all
// workers have relinquished their locked files.
std::unique_lock<std::mutex> lock(locked_blobs_mutex_);
locked_blobs_mutex_cond_var_.wait(lock, [&] { return locked_blobs_.empty(); });
DIR* dir = opendir(user_dir.c_str());
if (!dir) {
ALOGW("can't open directory for user: %s", strerror(errno));
return std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>&&>{ResponseCode::SYSTEM_ERROR,
std::move(matches)};
}
struct dirent* file;
while ((file = readdir(dir)) != nullptr) {
// We only care about files.
if (file->d_type != DT_REG) {
continue;
}
// Skip anything that starts with a "."
if (file->d_name[0] == '.') {
continue;
}
auto [success, uid, alias] = filename2UidAlias(file->d_name);
if (!success) {
ALOGW("could not parse key filename \"%s\"", file->d_name);
continue;
}
if (!filter(uid, alias)) continue;
auto [iterator, dummy] = locked_blobs_.emplace(alias, user_dir, uid);
matches.push_back(*iterator);
}
closedir(dir);
return std::tuple<ResponseCode, std::list<LockedKeyBlobEntry>&&>{ResponseCode::NO_ERROR,
std::move(matches)};
}