2016-01-27 06:44:56 +01:00
|
|
|
/*
|
|
|
|
* 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 <cutils/log.h>
|
|
|
|
|
|
|
|
#include "blob.h"
|
|
|
|
#include "entropy.h"
|
|
|
|
|
|
|
|
#include "keystore_utils.h"
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
constexpr size_t kGcmIvSizeBytes = 96 / 8;
|
|
|
|
|
|
|
|
template <typename T, void (*FreeFunc)(T*)> struct OpenSslObjectDeleter {
|
|
|
|
void operator()(T* p) { FreeFunc(p); }
|
|
|
|
};
|
|
|
|
|
|
|
|
#define DEFINE_OPENSSL_OBJECT_POINTER(name) \
|
|
|
|
typedef OpenSslObjectDeleter<name, name##_free> name##_Delete; \
|
|
|
|
typedef std::unique_ptr<name, name##_Delete> name##_Ptr;
|
|
|
|
|
|
|
|
DEFINE_OPENSSL_OBJECT_POINTER(EVP_CIPHER_CTX);
|
|
|
|
|
2017-05-26 18:13:28 +02:00
|
|
|
#if defined(__clang__)
|
2017-04-18 18:47:57 +02:00
|
|
|
#define OPTNONE __attribute__((optnone))
|
2017-05-26 18:13:28 +02:00
|
|
|
#elif defined(__GNUC__)
|
2017-04-18 18:47:57 +02:00
|
|
|
#define OPTNONE __attribute__((optimize("O0")))
|
2017-05-26 18:13:28 +02:00
|
|
|
#else
|
|
|
|
#error Need a definition for OPTNONE
|
|
|
|
#endif
|
2017-04-18 18:47:57 +02:00
|
|
|
|
|
|
|
class ArrayEraser {
|
|
|
|
public:
|
|
|
|
ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
|
|
|
|
OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
|
|
|
|
|
|
|
|
private:
|
2017-05-26 18:13:28 +02:00
|
|
|
volatile uint8_t* mArr;
|
2017-04-18 18:47:57 +02:00
|
|
|
size_t mSize;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Encrypt 'len' data at 'in' with AES-GCM, using 128-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 uint8_t* key,
|
|
|
|
const uint8_t* iv, uint8_t* tag) {
|
|
|
|
const EVP_CIPHER* cipher = EVP_aes_128_gcm();
|
|
|
|
EVP_CIPHER_CTX_Ptr ctx(EVP_CIPHER_CTX_new());
|
|
|
|
|
|
|
|
EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, 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 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 uint8_t* key,
|
|
|
|
const uint8_t* iv, const uint8_t* tag) {
|
|
|
|
const EVP_CIPHER* cipher = EVP_aes_128_gcm();
|
|
|
|
EVP_CIPHER_CTX_Ptr ctx(EVP_CIPHER_CTX_new());
|
|
|
|
|
|
|
|
EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, 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)) {
|
|
|
|
ALOGD("Failed to decrypt blob; ciphertext or tag is likely corrupted");
|
|
|
|
return ResponseCode::SYSTEM_ERROR;
|
|
|
|
}
|
|
|
|
out_pos += out_len;
|
|
|
|
if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
|
|
|
|
ALOGD("Encrypted plaintext 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);
|
|
|
|
|
|
|
|
return ResponseCode::NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2016-01-27 06:44:56 +01:00
|
|
|
Blob::Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
|
|
|
|
BlobType type) {
|
|
|
|
memset(&mBlob, 0, sizeof(mBlob));
|
2017-04-18 18:47:57 +02:00
|
|
|
if (valueLength > kValueSize) {
|
|
|
|
valueLength = kValueSize;
|
2016-01-27 06:44:56 +01:00
|
|
|
ALOGW("Provided blob length too large");
|
|
|
|
}
|
2017-04-18 18:47:57 +02:00
|
|
|
if (infoLength + valueLength > kValueSize) {
|
|
|
|
infoLength = kValueSize - valueLength;
|
2016-01-27 06:44:56 +01:00
|
|
|
ALOGW("Provided info length too large");
|
|
|
|
}
|
|
|
|
mBlob.length = valueLength;
|
|
|
|
memcpy(mBlob.value, value, valueLength);
|
|
|
|
|
|
|
|
mBlob.info = infoLength;
|
|
|
|
memcpy(mBlob.value + valueLength, info, infoLength);
|
|
|
|
|
|
|
|
mBlob.version = CURRENT_BLOB_VERSION;
|
|
|
|
mBlob.type = uint8_t(type);
|
|
|
|
|
|
|
|
if (type == TYPE_MASTER_KEY) {
|
|
|
|
mBlob.flags = KEYSTORE_FLAG_ENCRYPTED;
|
|
|
|
} else {
|
|
|
|
mBlob.flags = KEYSTORE_FLAG_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
Blob::Blob(blobv3 b) {
|
2016-01-27 06:44:56 +01:00
|
|
|
mBlob = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
Blob::Blob() {
|
|
|
|
memset(&mBlob, 0, sizeof(mBlob));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Blob::isEncrypted() const {
|
|
|
|
if (mBlob.version < 2) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED;
|
|
|
|
}
|
|
|
|
|
2017-02-28 21:53:24 +01:00
|
|
|
bool Blob::isSuperEncrypted() const {
|
|
|
|
return mBlob.flags & KEYSTORE_FLAG_SUPER_ENCRYPTED;
|
|
|
|
}
|
|
|
|
|
2017-04-21 20:15:13 +02:00
|
|
|
bool Blob::isCriticalToDeviceEncryption() const {
|
|
|
|
return mBlob.flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
|
|
|
|
}
|
|
|
|
|
2017-02-28 21:53:24 +01:00
|
|
|
inline uint8_t setFlag(uint8_t flags, bool set, KeyStoreFlag flag) {
|
|
|
|
return set ? (flags | flag) : (flags & ~flag);
|
|
|
|
}
|
|
|
|
|
2016-01-27 06:44:56 +01:00
|
|
|
void Blob::setEncrypted(bool encrypted) {
|
2017-02-28 21:53:24 +01:00
|
|
|
mBlob.flags = setFlag(mBlob.flags, encrypted, KEYSTORE_FLAG_ENCRYPTED);
|
|
|
|
}
|
|
|
|
|
2017-04-21 20:15:13 +02:00
|
|
|
void Blob::setSuperEncrypted(bool superEncrypted) {
|
|
|
|
mBlob.flags = setFlag(mBlob.flags, superEncrypted, KEYSTORE_FLAG_SUPER_ENCRYPTED);
|
|
|
|
}
|
2017-04-19 15:16:57 +02:00
|
|
|
|
2017-04-21 20:15:13 +02:00
|
|
|
void Blob::setCriticalToDeviceEncryption(bool critical) {
|
|
|
|
mBlob.flags = setFlag(mBlob.flags, critical, KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Blob::setFallback(bool fallback) {
|
|
|
|
if (fallback) {
|
|
|
|
mBlob.flags |= KEYSTORE_FLAG_FALLBACK;
|
|
|
|
} else {
|
|
|
|
mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
ResponseCode Blob::writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
|
2016-01-27 06:44:56 +01:00
|
|
|
Entropy* entropy) {
|
2017-04-18 18:47:57 +02:00
|
|
|
ALOGV("writing blob %s", filename.c_str());
|
|
|
|
|
|
|
|
const size_t dataLength = mBlob.length;
|
|
|
|
mBlob.length = htonl(mBlob.length);
|
|
|
|
|
2017-02-28 21:53:24 +01:00
|
|
|
if (isEncrypted() || isSuperEncrypted()) {
|
2016-01-27 06:44:56 +01:00
|
|
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
memset(mBlob.initialization_vector, 0, AES_BLOCK_SIZE);
|
|
|
|
if (!entropy->generate_random_data(mBlob.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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
auto rc = AES_gcm_encrypt(mBlob.value /* in */, mBlob.value /* out */, dataLength, aes_key,
|
|
|
|
mBlob.initialization_vector, mBlob.aead_tag);
|
|
|
|
if (rc != ResponseCode::NO_ERROR) return rc;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
size_t fileLength = offsetof(blobv3, value) + dataLength + mBlob.info;
|
2016-01-27 06:44:56 +01:00
|
|
|
|
|
|
|
const char* tmpFileName = ".tmp";
|
|
|
|
int out =
|
|
|
|
TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
|
|
|
|
if (out < 0) {
|
|
|
|
ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno));
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
2017-04-18 18:47:57 +02:00
|
|
|
|
|
|
|
const size_t writtenBytes = writeFully(out, (uint8_t*)&mBlob, fileLength);
|
2016-01-27 06:44:56 +01:00
|
|
|
if (close(out) != 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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
if (writtenBytes != fileLength) {
|
|
|
|
ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
|
|
|
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
2017-04-18 18:47:57 +02:00
|
|
|
if (rename(tmpFileName, filename.c_str()) == -1) {
|
|
|
|
ALOGW("could not rename blob to %s: %s", filename.c_str(), strerror(errno));
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
ResponseCode Blob::readBlob(const std::string& filename, const uint8_t* aes_key, State state) {
|
|
|
|
ALOGV("reading blob %s", filename.c_str());
|
|
|
|
const int in = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY));
|
2016-01-27 06:44:56 +01:00
|
|
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
2017-04-18 18:47:57 +02:00
|
|
|
|
|
|
|
// fileLength may be less than sizeof(mBlob)
|
|
|
|
const size_t fileLength = readFully(in, (uint8_t*)&mBlob, sizeof(mBlob));
|
2016-01-27 06:44:56 +01:00
|
|
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fileLength == 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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
2017-09-01 23:31:36 +02:00
|
|
|
if ((isEncrypted() || isSuperEncrypted())) {
|
|
|
|
if (state == STATE_LOCKED) return ResponseCode::LOCKED;
|
|
|
|
if (state == STATE_UNINITIALIZED) return ResponseCode::UNINITIALIZED;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
if (fileLength < offsetof(blobv3, value)) return ResponseCode::VALUE_CORRUPTED;
|
2016-01-27 06:44:56 +01:00
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
if (mBlob.version == 3) {
|
|
|
|
const ssize_t encryptedLength = ntohl(mBlob.length);
|
2016-01-27 06:44:56 +01:00
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
if (isEncrypted() || isSuperEncrypted()) {
|
|
|
|
auto rc = AES_gcm_decrypt(mBlob.value /* in */, mBlob.value /* out */, encryptedLength,
|
|
|
|
aes_key, mBlob.initialization_vector, mBlob.aead_tag);
|
|
|
|
if (rc != ResponseCode::NO_ERROR) return rc;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
2017-04-18 18:47:57 +02:00
|
|
|
} else if (mBlob.version < 3) {
|
|
|
|
blobv2& blob = reinterpret_cast<blobv2&>(mBlob);
|
|
|
|
const size_t headerLength = offsetof(blobv2, encrypted);
|
|
|
|
const ssize_t encryptedLength = fileLength - headerLength - blob.info;
|
|
|
|
if (encryptedLength < 0) return ResponseCode::VALUE_CORRUPTED;
|
|
|
|
|
|
|
|
if (isEncrypted() || isSuperEncrypted()) {
|
|
|
|
if (encryptedLength % AES_BLOCK_SIZE != 0) {
|
|
|
|
return ResponseCode::VALUE_CORRUPTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
AES_KEY key;
|
|
|
|
AES_set_decrypt_key(aes_key, kAesKeySize * 8, &key);
|
|
|
|
AES_cbc_encrypt(blob.encrypted, blob.encrypted, encryptedLength, &key, blob.vector,
|
|
|
|
AES_DECRYPT);
|
|
|
|
key = {}; // clear key
|
|
|
|
|
|
|
|
uint8_t computedDigest[MD5_DIGEST_LENGTH];
|
|
|
|
ssize_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
|
|
|
|
MD5(blob.digested, digestedLength, computedDigest);
|
|
|
|
if (memcmp(blob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
|
|
|
|
return ResponseCode::VALUE_CORRUPTED;
|
|
|
|
}
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-18 18:47:57 +02:00
|
|
|
const ssize_t maxValueLength = fileLength - offsetof(blobv3, value) - mBlob.info;
|
2016-01-27 06:44:56 +01:00
|
|
|
mBlob.length = ntohl(mBlob.length);
|
2017-04-18 18:47:57 +02:00
|
|
|
if (mBlob.length < 0 || mBlob.length > maxValueLength ||
|
|
|
|
mBlob.length + mBlob.info + AES_BLOCK_SIZE > static_cast<ssize_t>(sizeof(mBlob.value))) {
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
2017-04-18 18:47:57 +02:00
|
|
|
|
|
|
|
if (mBlob.info != 0 && mBlob.version < 3) {
|
2016-01-27 06:44:56 +01:00
|
|
|
// move info from after padding to after data
|
2017-04-18 18:47:57 +02:00
|
|
|
memmove(mBlob.value + mBlob.length, mBlob.value + maxValueLength, mBlob.info);
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
2017-04-18 18:47:57 +02:00
|
|
|
|
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;
|
2016-01-27 06:44:56 +01:00
|
|
|
}
|
2017-12-19 01:48:46 +01:00
|
|
|
|
|
|
|
keystore::SecurityLevel Blob::getSecurityLevel() const {
|
|
|
|
return keystore::flagsToSecurityLevel(mBlob.flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Blob::setSecurityLevel(keystore::SecurityLevel secLevel) {
|
|
|
|
mBlob.flags &= ~(KEYSTORE_FLAG_FALLBACK | KEYSTORE_FLAG_STRONGBOX);
|
|
|
|
mBlob.flags |= keystore::securityLevelToFlags(secLevel);
|
|
|
|
}
|