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
TEST(HmacAuthorizationDelegateTest,UninitializedSessionTest)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
TEST(HmacAuthorizationDelegateTest,SessionKeyTest)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
TEST(HmacAuthorizationDelegateTest,EncryptDecryptTest)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:
HmacAuthorizationDelegateFixture()94 HmacAuthorizationDelegateFixture() {}
~HmacAuthorizationDelegateFixture()95 ~HmacAuthorizationDelegateFixture() override {}
96
SetUp()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
TEST_F(HmacAuthorizationDelegateFixture,NonceRegenerationTest)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
TEST_F(HmacAuthorizationDelegateFixture,CommandAuthTest)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
TEST_F(HmacAuthorizationDelegateFixture,ResponseAuthTest)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
TEST_F(HmacAuthorizationDelegateFixture,SessionAttributes)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