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