• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&parameter));
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