summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRubin Xu <rubinxu@google.com>2017-10-23 17:04:25 +0100
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-10-24 06:11:03 +0000
commit4fb39a3280d15b998713da12255743384984fc01 (patch)
tree39fb0ba2319e741f7c71f66dbf06fdf0909186c2
parent8638c76156bc1cfb13c77d3ea10b8996063b74bb (diff)
downloadsecurity-4fb39a3280d15b998713da12255743384984fc01.tar.gz
Handle auth token with same timestamp
We observed on some Pixel C that they sometimes generate auth token with a stuck timestamp value. Since the timestamp value does not increase, newer auth token is not considered "superceding" old auth tokens and keystore end up retrieving older auth tokens which are then treated as expired due to its time_received value being too old. We workaround this issue by comparing both the timestamp (which is part of auth token) and the time_received (which is a monotonic clock value at the time auth token is sent to keystore). So a new auth token with stuck timestamp value but newer time_received still supercedes older auth tokens. This is actually sufficient to workaround the issue on Pixel C, since the stuck timestamp value is returned by the secure RTC, whose value is also used by keymaster TA to check key authorization. In other words, the auth token is still good to authorize auth-bound keys, even with a stuck timestamp value. This does mean that on the affected Pixel C, auth-bound keys are not enforced at TrustZone leve, but merely a logical check in keystore daemon. Bug: 65283496 Test: boot device, unlock successfully Change-Id: I0b9d5463e94241bfaf552dcb31fea04ee966596c (cherry picked from commit bfb01d904d403087d096658d3830b34d0f931714)
-rw-r--r--keystore/auth_token_table.cpp2
-rw-r--r--keystore/auth_token_table.h10
2 files changed, 9 insertions, 3 deletions
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index 8b81e472..46b644d1 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -244,7 +244,7 @@ bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
return (token_->userId == entry.token_->userId &&
token_->authenticatorType == entry.token_->authenticatorType &&
token_->authenticatorId == entry.token_->authenticatorId &&
- timestamp_host_order() > entry.timestamp_host_order());
+ is_newer_than(&entry));
}
} // namespace keymaster
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 422c7102..0056b268 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -114,9 +114,15 @@ class AuthTokenTable {
bool Supersedes(const Entry& entry) const;
bool SatisfiesAuth(const std::vector<uint64_t>& sids, HardwareAuthenticatorType auth_type);
- bool is_newer_than(const Entry* entry) {
+ bool is_newer_than(const Entry* entry) const {
if (!entry) return true;
- return timestamp_host_order() > entry->timestamp_host_order();
+ uint64_t ts = timestamp_host_order();
+ uint64_t other_ts = entry->timestamp_host_order();
+ // Normally comparing timestamp_host_order alone is sufficient, but here is an
+ // additional hack to compare time_received value for some devices where their auth
+ // tokens contain fixed timestamp (due to the a stuck secure RTC on them)
+ return (ts > other_ts) ||
+ ((ts == other_ts) && (time_received_ > entry->time_received_));
}
void mark_completed() { operation_completed_ = true; }