1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "KeymasterHidlTest.h" 18 19namespace android { 20namespace hardware { 21namespace keymaster { 22namespace V4_0 { 23namespace test { 24 25class VerificationTokenTest : public KeymasterHidlTest { 26 protected: 27 struct VerifyAuthorizationResult { 28 bool callSuccessful; 29 ErrorCode error; 30 VerificationToken token; 31 }; 32 33 VerifyAuthorizationResult verifyAuthorization(uint64_t operationHandle, 34 const AuthorizationSet& paramsToVerify, 35 const HardwareAuthToken& authToken) { 36 VerifyAuthorizationResult result; 37 result.callSuccessful = 38 keymaster() 39 .verifyAuthorization(operationHandle, paramsToVerify.hidl_data(), authToken, 40 [&](auto error, auto token) { 41 result.error = error; 42 result.token = token; 43 }) 44 .isOk(); 45 return result; 46 } 47 48 uint64_t getTime() { 49 struct timespec timespec; 50 EXPECT_EQ(0, clock_gettime(CLOCK_BOOTTIME, ×pec)); 51 return timespec.tv_sec * 1000 + timespec.tv_nsec / 1000000; 52 } 53 54 int sleep_ms(uint32_t milliseconds) { 55 struct timespec sleep_time = {static_cast<time_t>(milliseconds / 1000), 56 static_cast<long>(milliseconds % 1000) * 1000000}; 57 while (sleep_time.tv_sec || sleep_time.tv_nsec) { 58 if (nanosleep(&sleep_time /* to wait */, 59 &sleep_time /* remaining (on interrruption) */) == 0) { 60 sleep_time = {}; 61 } else { 62 if (errno != EINTR) return errno; 63 } 64 } 65 return 0; 66 } 67 68}; // namespace test 69 70/* 71 * VerificationTokens exist to facilitate cross-Keymaster verification of requirements. As 72 * such, the precise capabilities required will vary depending on the specific vendor 73 * implementations. Essentially, VerificationTokens are a "hook" to enable vendor 74 * implementations to communicate, so the precise usage is defined by those vendors. The only 75 * thing we really can test is that tokens can be created by TEE keymasters, and that the 76 * timestamps increase as expected. 77 */ 78TEST_F(VerificationTokenTest, TestCreation) { 79 auto result1 = verifyAuthorization( 80 1 /* operation handle */, AuthorizationSet() /* paramtersToVerify */, HardwareAuthToken()); 81 ASSERT_TRUE(result1.callSuccessful); 82 auto result1_time = getTime(); 83 84 if (SecLevel() == SecurityLevel::STRONGBOX) { 85 // StrongBox should not implement verifyAuthorization. 86 EXPECT_EQ(ErrorCode::UNIMPLEMENTED, result1.error); 87 return; 88 } 89 90 EXPECT_EQ(ErrorCode::OK, result1.error); 91 EXPECT_EQ(1U, result1.token.challenge); 92 EXPECT_EQ(SecLevel(), result1.token.securityLevel); 93 EXPECT_EQ(0U, result1.token.parametersVerified.size()) 94 << "We didn't supply any parameters to verify"; 95 EXPECT_GT(result1.token.timestamp, 0U); 96 97 constexpr uint32_t time_to_sleep = 200; 98 sleep_ms(time_to_sleep); 99 100 auto result2 = verifyAuthorization( 101 2 /* operation handle */, AuthorizationSet() /* paramtersToVerify */, HardwareAuthToken()); 102 ASSERT_TRUE(result2.callSuccessful); 103 auto result2_time = getTime(); 104 EXPECT_EQ(ErrorCode::OK, result2.error); 105 EXPECT_EQ(2U, result2.token.challenge); 106 EXPECT_EQ(SecLevel(), result2.token.securityLevel); 107 EXPECT_EQ(0U, result2.token.parametersVerified.size()) 108 << "We didn't supply any parameters to verify"; 109 110 auto host_time_delta = result2_time - result1_time; 111 112 EXPECT_GE(host_time_delta, time_to_sleep) 113 << "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much"; 114 EXPECT_LE(host_time_delta, time_to_sleep + 10) 115 << "The verifyAuthorization call took more than 10 ms? That's awful!"; 116 117 auto km_time_delta = result2.token.timestamp - result1.token.timestamp; 118 119 // If not too much else is going on on the system, the time delta should be quite close. Allow 120 // 2 ms of slop just to avoid test flakiness. 121 // 122 // TODO(swillden): see if we can output values so they can be gathered across many runs and 123 // report if times aren't nearly always <1ms apart. 124 EXPECT_LE(host_time_delta, km_time_delta + 2); 125 EXPECT_LE(km_time_delta, host_time_delta + 2); 126} 127 128} // namespace test 129} // namespace V4_0 130} // namespace keymaster 131} // namespace hardware 132} // namespace android 133