/* * Copyright 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. */ #include "trusty_keymaster_enforcement.h" #include #include #include #include #include #include #include "trusty_keymaster_context.h" namespace keymaster { keymaster_security_level_t TrustyKeymasterEnforcement::SecurityLevel() const { return KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT; } bool TrustyKeymasterEnforcement::auth_token_timed_out( const hw_auth_token_t& token, uint32_t timeout_seconds) const { uint64_t token_timestamp_millis = ntoh(token.timestamp); uint64_t timeout_millis = static_cast(timeout_seconds) * 1000; uint64_t millis_since_boot = milliseconds_since_boot(); return (millis_since_boot >= token_timestamp_millis && (millis_since_boot - token_timestamp_millis) > timeout_millis); } uint64_t TrustyKeymasterEnforcement::get_current_time_ms() const { return milliseconds_since_boot(); } inline size_t min(size_t a, size_t b) { return a < b ? a : b; } bool TrustyKeymasterEnforcement::ValidateTokenSignature( const hw_auth_token_t& token) const { keymaster_key_blob_t auth_token_key; keymaster_error_t error = context_->GetAuthTokenKey(&auth_token_key); if (error != KM_ERROR_OK) return false; // Signature covers entire token except HMAC field. const uint8_t* hash_data = reinterpret_cast(&token); size_t hash_data_length = reinterpret_cast(&token.hmac) - hash_data; uint8_t computed_hash[EVP_MAX_MD_SIZE]; unsigned int computed_hash_length; if (!HMAC(EVP_sha256(), auth_token_key.key_material, auth_token_key.key_material_size, hash_data, hash_data_length, computed_hash, &computed_hash_length)) { LOG_S("Error %d computing token signature", TranslateLastOpenSslError()); return false; } return 0 == memcmp_s(computed_hash, token.hmac, min(sizeof(token.hmac), computed_hash_length)); } uint64_t TrustyKeymasterEnforcement::milliseconds_since_boot() const { int rv; int64_t secure_time_ns = 0; rv = trusty_gettime(0, &secure_time_ns); if (rv || secure_time_ns < 0) { LOG_S("Error getting time. Error: %d, time: %" PRId64, rv, secure_time_ns); secure_time_ns = 0xFFFFFFFFFFFFFFFFL; // UINT64_MAX isn't defined (b/22120972) } return static_cast(secure_time_ns) / 1000 / 1000; } } // namespace keymaster