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
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 4d54a39..6f7aab1 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -18,12 +18,14 @@
#include <vector>
#include <hardware/hw_auth_token.h>
-#include <keymaster/authorization_set.h>
+#include <keystore/authorization_set.h>
#ifndef KEYSTORE_AUTH_TOKEN_TABLE_H_
#define KEYSTORE_AUTH_TOKEN_TABLE_H_
-namespace keymaster {
+namespace keystore {
+
+using android::hardware::keymaster::V3_0::HardwareAuthToken;
namespace test {
class AuthTokenTableTest;
@@ -42,7 +44,8 @@
class AuthTokenTable {
public:
explicit AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
- : max_entries_(max_entries), last_off_body_(clock_function()), clock_function_(clock_function) {}
+ : max_entries_(max_entries), last_off_body_(clock_function()),
+ clock_function_(clock_function) {}
enum Error {
OK,
@@ -58,7 +61,7 @@
/**
* Add an authorization token to the table. The table takes ownership of the argument.
*/
- void AddAuthenticationToken(const hw_auth_token_t* token);
+ void AddAuthenticationToken(const HardwareAuthToken* token);
/**
* Find an authorization token that authorizes the operation specified by \p operation_handle on
@@ -70,30 +73,14 @@
*
* The table retains ownership of the returned object.
*/
- Error FindAuthorization(const AuthorizationSet& key_info, keymaster_purpose_t purpose,
- keymaster_operation_handle_t op_handle, const hw_auth_token_t** found);
-
- /**
- * Find an authorization token that authorizes the operation specified by \p operation_handle on
- * a key with the characteristics specified in \p key_info.
- *
- * This method is O(n * m), where n is the number of KM_TAG_USER_SECURE_ID entries in key_info
- * and m is the number of entries in the table. It could be made better, but n and m should
- * always be small.
- *
- * The table retains ownership of the returned object.
- */
- Error FindAuthorization(const keymaster_key_param_t* params, size_t params_count,
- keymaster_purpose_t purpose, keymaster_operation_handle_t op_handle,
- const hw_auth_token_t** found) {
- return FindAuthorization(AuthorizationSet(params, params_count), purpose, op_handle, found);
- }
+ Error FindAuthorization(const AuthorizationSet& key_info, KeyPurpose purpose,
+ uint64_t op_handle, const HardwareAuthToken** found);
/**
* Mark operation completed. This allows tokens associated with the specified operation to be
* superseded by new tokens.
*/
- void MarkCompleted(const keymaster_operation_handle_t op_handle);
+ void MarkCompleted(const uint64_t op_handle);
/**
* Update the last_off_body_ timestamp so that tokens which remain authorized only so long as
@@ -110,7 +97,7 @@
class Entry {
public:
- Entry(const hw_auth_token_t* token, time_t current_time);
+ Entry(const HardwareAuthToken* token, time_t current_time);
Entry(Entry&& entry) { *this = std::move(entry); }
void operator=(Entry&& rhs) {
@@ -125,36 +112,34 @@
void UpdateLastUse(time_t time);
bool Supersedes(const Entry& entry) const;
- bool SatisfiesAuth(const std::vector<uint64_t>& sids, hw_authenticator_type_t auth_type);
+ bool SatisfiesAuth(const std::vector<uint64_t>& sids, HardwareAuthenticatorType auth_type);
bool is_newer_than(const Entry* entry) {
- if (!entry)
- return true;
+ if (!entry) return true;
return timestamp_host_order() > entry->timestamp_host_order();
}
void mark_completed() { operation_completed_ = true; }
- const hw_auth_token_t* token() { return token_.get(); }
+ const HardwareAuthToken* token() { return token_.get(); }
time_t time_received() const { return time_received_; }
bool completed() const { return operation_completed_; }
uint32_t timestamp_host_order() const;
- hw_authenticator_type_t authenticator_type() const;
+ HardwareAuthenticatorType authenticator_type() const;
private:
- std::unique_ptr<const hw_auth_token_t> token_;
+ std::unique_ptr<const HardwareAuthToken> token_;
time_t time_received_;
time_t last_use_;
bool operation_completed_;
};
Error FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
- hw_authenticator_type_t auth_type,
- keymaster_operation_handle_t op_handle,
- const hw_auth_token_t** found);
+ HardwareAuthenticatorType auth_type, uint64_t op_handle,
+ const HardwareAuthToken** found);
Error FindTimedAuthorization(const std::vector<uint64_t>& sids,
- hw_authenticator_type_t auth_type,
- const AuthorizationSet& key_info, const hw_auth_token_t** found);
+ HardwareAuthenticatorType auth_type,
+ const AuthorizationSet& key_info, const HardwareAuthToken** found);
void ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids);
void RemoveEntriesSupersededBy(const Entry& entry);
bool IsSupersededBySomeEntry(const Entry& entry);