Fully support uint64 key validity dates.

This fixes the issue where, on 32-bit platforms, keys expiring after
about 2^31 - 1 seconds since epoch (Jan 19 2038) might be treated as
already expired.

The issue was caused by using time_t (signed 32-bit on 32-bit
platforms) as current time and downcasting uint64 activation and
expiration time instants to time_t to compare them to current time.
This downcasting could make future time instants appear to be in the
past on 32-bit platforms.

Bug: 22015107
Change-Id: Iae12019c3c019beb92d791fda80b622fa5c4ac4e
diff --git a/keystore/keystore_keymaster_enforcement.h b/keystore/keystore_keymaster_enforcement.h
index 904bf66..f7703eb 100644
--- a/keystore/keystore_keymaster_enforcement.h
+++ b/keystore/keystore_keymaster_enforcement.h
@@ -38,15 +38,38 @@
     }
 
     bool activation_date_valid(uint64_t activation_date) const override {
-        // Convert java date to time_t, non-portably.
-        time_t activation_time = activation_date / 1000;
-        return difftime(time(NULL), activation_time) >= 0;
+        time_t now = time(NULL);
+        if (now == static_cast<time_t>(-1)) {
+            // Failed to obtain current time -- fail safe: activation_date hasn't yet occurred.
+            return false;
+        } else if (now < 0) {
+            // Current time is prior to start of the epoch -- activation_date hasn't yet occurred.
+            return false;
+        }
+
+        // time(NULL) returns seconds since epoch and "loses" milliseconds information. We thus add
+        // 999 ms to now_date to avoid a situation where an activation_date of up to 999ms in the
+        // past may still be considered to still be in the future. This can be removed once
+        // time(NULL) is replaced by a millisecond-precise source of time.
+        uint64_t now_date = static_cast<uint64_t>(now) * 1000 + 999;
+        return now_date >= activation_date;
     }
 
     bool expiration_date_passed(uint64_t expiration_date) const override {
-        // Convert jave date to time_t, non-portably.
-        time_t expiration_time = expiration_date / 1000;
-        return difftime(time(NULL), expiration_time) > 0;
+        time_t now = time(NULL);
+        if (now == static_cast<time_t>(-1)) {
+            // Failed to obtain current time -- fail safe: expiration_date has passed.
+            return true;
+        } else if (now < 0) {
+            // Current time is prior to start of the epoch: expiration_date hasn't yet occurred.
+            return false;
+        }
+
+        // time(NULL) returns seconds since epoch and "loses" milliseconds information. As a result,
+        // expiration_date of up to 999 ms in the past may still be considered in the future. This
+        // is OK.
+        uint64_t now_date = static_cast<uint64_t>(now) * 1000;
+        return now_date > expiration_date;
     }
 
     bool auth_token_timed_out(const hw_auth_token_t&, uint32_t) const {