| /* |
| * 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 <openssl/hmac.h> |
| #include <trusty/time.h> |
| |
| #include <hardware/hw_auth_token.h> |
| #include <keymaster/android_keymaster_utils.h> |
| #include <keymaster/km_openssl/openssl_err.h> |
| |
| #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<uint64_t>(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<const uint8_t*>(&token); |
| size_t hash_data_length = |
| reinterpret_cast<const uint8_t*>(&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: %lld", rv, secure_time_ns); |
| secure_time_ns = |
| 0xFFFFFFFFFFFFFFFFL; // UINT64_MAX isn't defined (b/22120972) |
| } |
| return static_cast<uint64_t>(secure_time_ns) / 1000 / 1000; |
| } |
| |
| } // namespace keymaster |