Home | History | Annotate | Download | only in trunks
      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(&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 
    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