19221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden/*
29221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * Copyright (C) 2015 The Android Open Source Project
39221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden *
49221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * Licensed under the Apache License, Version 2.0 (the "License");
59221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * you may not use this file except in compliance with the License.
69221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * You may obtain a copy of the License at
79221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden *
89221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden *      http://www.apache.org/licenses/LICENSE-2.0
99221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden *
109221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * Unless required by applicable law or agreed to in writing, software
119221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * distributed under the License is distributed on an "AS IS" BASIS,
129221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * See the License for the specific language governing permissions and
149221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * limitations under the License.
159221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden */
169221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
17c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#ifndef KEYSTORE_KEYSTORE_KEYMASTER_ENFORCEMENT_H_
18c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#define KEYSTORE_KEYSTORE_KEYMASTER_ENFORCEMENT_H_
199221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
209221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden#include <time.h>
219221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
22c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include "keymaster_enforcement.h"
239221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
24c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisnamespace keystore {
259221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden/**
269221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * This is a specialization of the KeymasterEnforcement class to be used by Keystore to enforce
279221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden * keymaster requirements on all key operation.
289221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden */
29c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisclass KeystoreKeymasterEnforcement : public KeymasterEnforcement {
309221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden  public:
319221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    KeystoreKeymasterEnforcement() : KeymasterEnforcement(64, 64) {}
329221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
339221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    uint32_t get_current_time() const override {
349221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden        struct timespec tp;
359221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden        int err = clock_gettime(CLOCK_MONOTONIC, &tp);
369221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden        if (err || tp.tv_sec < 0)
379221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden            return 0;
389221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden        return static_cast<uint32_t>(tp.tv_sec);
399221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    }
409221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
419221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    bool activation_date_valid(uint64_t activation_date) const override {
4253752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        time_t now = time(NULL);
4353752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        if (now == static_cast<time_t>(-1)) {
4453752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            // Failed to obtain current time -- fail safe: activation_date hasn't yet occurred.
4553752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            return false;
4653752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        } else if (now < 0) {
4753752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            // Current time is prior to start of the epoch -- activation_date hasn't yet occurred.
4853752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            return false;
4953752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        }
5053752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin
5153752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        // time(NULL) returns seconds since epoch and "loses" milliseconds information. We thus add
5253752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        // 999 ms to now_date to avoid a situation where an activation_date of up to 999ms in the
5353752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        // past may still be considered to still be in the future. This can be removed once
5453752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        // time(NULL) is replaced by a millisecond-precise source of time.
5553752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        uint64_t now_date = static_cast<uint64_t>(now) * 1000 + 999;
5653752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        return now_date >= activation_date;
579221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    }
589221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
599221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    bool expiration_date_passed(uint64_t expiration_date) const override {
6053752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        time_t now = time(NULL);
6153752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        if (now == static_cast<time_t>(-1)) {
6253752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            // Failed to obtain current time -- fail safe: expiration_date has passed.
6353752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            return true;
6453752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        } else if (now < 0) {
6553752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            // Current time is prior to start of the epoch: expiration_date hasn't yet occurred.
6653752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin            return false;
6753752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        }
6853752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin
6953752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        // time(NULL) returns seconds since epoch and "loses" milliseconds information. As a result,
7053752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        // expiration_date of up to 999 ms in the past may still be considered in the future. This
7153752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        // is OK.
7253752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        uint64_t now_date = static_cast<uint64_t>(now) * 1000;
7353752414eab95d31d76db4bb088ac1d5499b5aaeAlex Klyubin        return now_date > expiration_date;
749221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    }
759221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
769221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    bool auth_token_timed_out(const hw_auth_token_t&, uint32_t) const {
7706114e6a1e1663c39b718224c4f326d844b15b98Shawn Willden        // Assume the token has not timed out, because AuthTokenTable would not have returned it if
7806114e6a1e1663c39b718224c4f326d844b15b98Shawn Willden        // the timeout were past.  Secure hardware will also check timeouts if it supports them.
7906114e6a1e1663c39b718224c4f326d844b15b98Shawn Willden        return false;
809221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    }
819221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
829221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    bool ValidateTokenSignature(const hw_auth_token_t&) const override {
839221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden        // Non-secure world cannot validate token signatures because it doesn't have access to the
849221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden        // signing key. Assume the token is good.
859221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden        return true;
869221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden    }
879221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden};
889221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden
89c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis} // namespace keystore
90c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis
91c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#endif  // KEYSTORE_KEYSTORE_KEYMASTER_ENFORCEMENT_H_
92