1 // 2 // Copyright (C) 2014 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 <string> 18 19 #include <gtest/gtest.h> 20 21 #include "trunks/hmac_authorization_delegate.h" 22 23 namespace trunks { 24 25 TEST(HmacAuthorizationDelegateTest, UninitializedSessionTest) { 26 HmacAuthorizationDelegate delegate; 27 std::string dummy; 28 std::string p_hash("test"); 29 EXPECT_FALSE(delegate.GetCommandAuthorization(p_hash, false, false, &dummy)); 30 EXPECT_EQ(0u, dummy.size()); 31 EXPECT_FALSE(delegate.CheckResponseAuthorization(p_hash, dummy)); 32 EXPECT_FALSE(delegate.EncryptCommandParameter(&dummy)); 33 EXPECT_FALSE(delegate.DecryptResponseParameter(&dummy)); 34 } 35 36 TEST(HmacAuthorizationDelegateTest, SessionKeyTest) { 37 HmacAuthorizationDelegate delegate; 38 TPM2B_NONCE nonce; 39 nonce.size = kAesKeySize; 40 memset(nonce.buffer, 0, nonce.size); 41 TPM_HANDLE dummy_handle = HMAC_SESSION_FIRST; 42 EXPECT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, std::string(), 43 std::string(), false)); 44 EXPECT_EQ(0u, delegate.session_key_.size()); 45 46 std::string dummy_auth = std::string("authorization"); 47 std::string dummy_salt = std::string("salt"); 48 EXPECT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, dummy_salt, 49 dummy_auth, false)); 50 EXPECT_EQ(kHashDigestSize, delegate.session_key_.size()); 51 // TODO(usanghi): Use TCG TPM2.0 test vectors when available. 52 std::string expected_key("\xfb\x2f\x3c\x33\x65\x3e\xdc\x47" 53 "\xda\xbe\x4e\xb7\xf4\x6c\x19\x4d" 54 "\xea\x50\xb2\x11\x54\x45\x32\x73" 55 "\x47\x38\xef\xb3\x4a\x82\x29\x94", 56 kHashDigestSize); 57 EXPECT_EQ(0, expected_key.compare(delegate.session_key_)); 58 } 59 60 TEST(HmacAuthorizationDelegateTest, EncryptDecryptTest) { 61 HmacAuthorizationDelegate delegate; 62 std::string plaintext_parameter("parameter"); 63 std::string encrypted_parameter(plaintext_parameter); 64 // Test with session not initialized. 65 EXPECT_FALSE(delegate.EncryptCommandParameter(&encrypted_parameter)); 66 EXPECT_FALSE(delegate.DecryptResponseParameter(&encrypted_parameter)); 67 // Test with encryption not enabled. 68 TPM_HANDLE dummy_handle = HMAC_SESSION_FIRST; 69 TPM2B_NONCE nonce; 70 nonce.size = kAesKeySize; 71 std::string salt("salt"); 72 ASSERT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, salt, 73 std::string(), false)); 74 EXPECT_TRUE(delegate.EncryptCommandParameter(&encrypted_parameter)); 75 EXPECT_EQ(0, plaintext_parameter.compare(encrypted_parameter)); 76 EXPECT_TRUE(delegate.DecryptResponseParameter(&encrypted_parameter)); 77 EXPECT_EQ(0, plaintext_parameter.compare(encrypted_parameter)); 78 // Test with encryption enabled. 79 ASSERT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, salt, 80 std::string(), true)); 81 EXPECT_TRUE(delegate.EncryptCommandParameter(&encrypted_parameter)); 82 EXPECT_NE(0, plaintext_parameter.compare(encrypted_parameter)); 83 // Calling EncryptCommandParameter regenerated the caller_nonce. 84 // We need to manually switch tpm_nonce and caller_nonce to ensure 85 // that DecryptResponseParameter has the correct nonces. 86 delegate.tpm_nonce_ = delegate.caller_nonce_; 87 delegate.caller_nonce_ = nonce; 88 EXPECT_TRUE(delegate.DecryptResponseParameter(&encrypted_parameter)); 89 EXPECT_EQ(0, plaintext_parameter.compare(encrypted_parameter)); 90 } 91 92 class HmacAuthorizationDelegateFixture : public testing::Test { 93 public: 94 HmacAuthorizationDelegateFixture() {} 95 ~HmacAuthorizationDelegateFixture() override {} 96 97 void SetUp() override { 98 session_handle_ = HMAC_SESSION_FIRST; 99 session_nonce_.size = kAesKeySize; 100 memset(session_nonce_.buffer, 0, kAesKeySize); 101 ASSERT_TRUE(delegate_.InitSession(session_handle_, 102 session_nonce_, // TPM nonce. 103 session_nonce_, // Caller nonce. 104 std::string(), // Salt. 105 std::string(), // Bind auth value. 106 false)); // Enable encryption. 107 } 108 109 protected: 110 TPM_HANDLE session_handle_; 111 TPM2B_NONCE session_nonce_; 112 HmacAuthorizationDelegate delegate_; 113 }; 114 115 TEST_F(HmacAuthorizationDelegateFixture, NonceRegenerationTest) { 116 ASSERT_TRUE(delegate_.InitSession(session_handle_, 117 session_nonce_, // TPM nonce. 118 session_nonce_, // Caller nonce. 119 std::string(), // Salt. 120 std::string(), // Bind auth value. 121 true)); // Enable encryption. 122 TPM2B_NONCE original_nonce = session_nonce_; 123 EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size); 124 EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, 125 original_nonce.buffer, 126 original_nonce.size)); 127 // First we check that performing GetCommandAuthorization resets the nonce. 128 std::string command_hash; 129 std::string authorization; 130 TPMS_AUTH_COMMAND auth_command; 131 EXPECT_TRUE(delegate_.GetCommandAuthorization(command_hash, false, false, 132 &authorization)); 133 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 134 &auth_command, 135 nullptr)); 136 EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size); 137 EXPECT_EQ(auth_command.nonce.size, original_nonce.size); 138 EXPECT_NE(0, memcmp(delegate_.caller_nonce_.buffer, 139 original_nonce.buffer, 140 original_nonce.size)); 141 EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, 142 auth_command.nonce.buffer, 143 auth_command.nonce.size)); 144 // Now we check that GetCommandAuthorization does not reset nonce 145 // when EncryptCommandParameter is called first. 146 original_nonce = delegate_.caller_nonce_; 147 std::string parameter; 148 EXPECT_TRUE(delegate_.EncryptCommandParameter(¶meter)); 149 EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size); 150 EXPECT_NE(0, memcmp(delegate_.caller_nonce_.buffer, 151 original_nonce.buffer, 152 original_nonce.size)); 153 EXPECT_TRUE(delegate_.nonce_generated_); 154 original_nonce = delegate_.caller_nonce_; 155 EXPECT_TRUE(delegate_.GetCommandAuthorization(command_hash, false, false, 156 &authorization)); 157 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 158 &auth_command, 159 nullptr)); 160 EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size); 161 EXPECT_EQ(auth_command.nonce.size, original_nonce.size); 162 EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, 163 original_nonce.buffer, 164 original_nonce.size)); 165 EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, 166 auth_command.nonce.buffer, 167 auth_command.nonce.size)); 168 } 169 170 TEST_F(HmacAuthorizationDelegateFixture, CommandAuthTest) { 171 std::string command_hash; 172 std::string authorization; 173 EXPECT_TRUE(delegate_.GetCommandAuthorization(command_hash, false, false, 174 &authorization)); 175 TPMS_AUTH_COMMAND auth_command; 176 std::string auth_bytes; 177 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 178 &auth_command, 179 &auth_bytes)); 180 EXPECT_EQ(auth_command.session_handle, session_handle_); 181 EXPECT_EQ(auth_command.nonce.size, session_nonce_.size); 182 EXPECT_EQ(kContinueSession, auth_command.session_attributes); 183 EXPECT_EQ(kHashDigestSize, auth_command.hmac.size); 184 } 185 186 TEST_F(HmacAuthorizationDelegateFixture, ResponseAuthTest) { 187 TPMS_AUTH_RESPONSE auth_response; 188 auth_response.session_attributes = kContinueSession; 189 auth_response.nonce.size = kAesKeySize; 190 memset(auth_response.nonce.buffer, 0, kAesKeySize); 191 auth_response.hmac.size = kHashDigestSize; 192 // TODO(usanghi): Use TCG TPM2.0 test vectors when available. 193 uint8_t hmac_buffer[kHashDigestSize] = 194 {0x37, 0x69, 0xaf, 0x12, 0xff, 0x4d, 0xbf, 0x44, 195 0xe5, 0x16, 0xa2, 0x2d, 0x1d, 0x05, 0x12, 0xe8, 196 0xbc, 0x42, 0x51, 0x6d, 0x59, 0xe8, 0xbf, 0x40, 197 0x1e, 0xa3, 0x46, 0xa4, 0xd6, 0x0d, 0xcc, 0xf7}; 198 memcpy(auth_response.hmac.buffer, hmac_buffer, kHashDigestSize); 199 std::string response_hash; 200 std::string authorization; 201 EXPECT_EQ(TPM_RC_SUCCESS, Serialize_TPMS_AUTH_RESPONSE(auth_response, 202 &authorization)); 203 EXPECT_TRUE(delegate_.CheckResponseAuthorization(response_hash, 204 authorization)); 205 } 206 207 TEST_F(HmacAuthorizationDelegateFixture, SessionAttributes) { 208 const uint8_t kDecryptSession = 1<<5; 209 const uint8_t kEncryptSession = 1<<6; 210 211 // Encryption disabled and not possible for command. 212 std::string authorization; 213 EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), false, false, 214 &authorization)); 215 TPMS_AUTH_COMMAND auth_command; 216 std::string auth_bytes; 217 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 218 &auth_command, 219 &auth_bytes)); 220 EXPECT_EQ(kContinueSession, auth_command.session_attributes); 221 222 // Encryption disabled and possible for command. 223 EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), true, true, 224 &authorization)); 225 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 226 &auth_command, 227 &auth_bytes)); 228 EXPECT_EQ(kContinueSession, auth_command.session_attributes); 229 230 // Encryption enabled and not possible for command. 231 ASSERT_TRUE(delegate_.InitSession(session_handle_, 232 session_nonce_, // TPM nonce. 233 session_nonce_, // Caller nonce. 234 std::string(), // Salt. 235 std::string(), // Bind auth value. 236 true)); // Enable encryption. 237 EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), false, false, 238 &authorization)); 239 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 240 &auth_command, 241 &auth_bytes)); 242 EXPECT_EQ(kContinueSession, auth_command.session_attributes); 243 244 // Encryption enabled and possible only for command input. 245 EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), true, false, 246 &authorization)); 247 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 248 &auth_command, 249 &auth_bytes)); 250 EXPECT_EQ(kContinueSession | kDecryptSession, 251 auth_command.session_attributes); 252 253 // Encryption enabled and possible only for command output. 254 EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), false, true, 255 &authorization)); 256 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 257 &auth_command, 258 &auth_bytes)); 259 EXPECT_EQ(kContinueSession | kEncryptSession, 260 auth_command.session_attributes); 261 262 // Encryption enabled and possible for command input and output. 263 EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), true, true, 264 &authorization)); 265 EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(&authorization, 266 &auth_command, 267 &auth_bytes)); 268 EXPECT_EQ(kContinueSession | kEncryptSession | kDecryptSession, 269 auth_command.session_attributes); 270 } 271 272 } // namespace trunks 273