Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  */
     24 
     25 #include <stdio.h>
     26 #include <string.h>
     27 
     28 #include <base/files/file_util.h>
     29 #include <gtest/gtest.h>
     30 #include <openssl/sha.h>
     31 
     32 #include "avb_unittest_util.h"
     33 #include "examples/things/avb_atx_slot_verify.h"
     34 #include "fake_avb_ops.h"
     35 
     36 namespace {
     37 
     38 const char kMetadataPath[] = "test/data/atx_metadata.bin";
     39 const char kPermanentAttributesPath[] =
     40     "test/data/atx_permanent_attributes.bin";
     41 const uint64_t kNewRollbackValue = 42;
     42 
     43 } /* namespace */
     44 
     45 namespace avb {
     46 
     47 // A fixture for testing avb_atx_slot_verify() with ATX. This test is
     48 // parameterized on the initial stored rollback index (same value used in all
     49 // relevant locations).
     50 class AvbAtxSlotVerifyExampleTest
     51     : public BaseAvbToolTest,
     52       public FakeAvbOpsDelegateWithDefaults,
     53       public ::testing::WithParamInterface<uint64_t> {
     54  public:
     55   ~AvbAtxSlotVerifyExampleTest() override = default;
     56 
     57   void SetUp() override {
     58     BaseAvbToolTest::SetUp();
     59     ReadAtxDefaultData();
     60     ops_.set_partition_dir(testdir_);
     61     ops_.set_delegate(this);
     62     ops_.set_permanent_attributes(attributes_);
     63     ops_.set_stored_is_device_unlocked(false);
     64   }
     65 
     66   // FakeAvbOpsDelegate overrides.
     67   AvbIOResult validate_vbmeta_public_key(AvbOps* ops,
     68                                          const uint8_t* public_key_data,
     69                                          size_t public_key_length,
     70                                          const uint8_t* public_key_metadata,
     71                                          size_t public_key_metadata_length,
     72                                          bool* out_key_is_trusted) override {
     73     // Send to ATX implementation.
     74     ++num_atx_calls_;
     75     return avb_atx_validate_vbmeta_public_key(ops,
     76                                               public_key_data,
     77                                               public_key_length,
     78                                               public_key_metadata,
     79                                               public_key_metadata_length,
     80                                               out_key_is_trusted);
     81   }
     82 
     83   AvbIOResult write_rollback_index(AvbOps* ops,
     84                                    size_t rollback_index_slot,
     85                                    uint64_t rollback_index) override {
     86     num_write_rollback_calls_++;
     87     return ops_.write_rollback_index(ops, rollback_index_slot, rollback_index);
     88   }
     89 
     90   void set_key_version(size_t rollback_index_location,
     91                        uint64_t key_version) override {
     92     num_key_version_calls_++;
     93     return ops_.set_key_version(rollback_index_location, key_version);
     94   }
     95 
     96   void RunSlotVerify() {
     97     ops_.set_stored_rollback_indexes(
     98         {{0, initial_rollback_value_},
     99          {AVB_ATX_PIK_VERSION_LOCATION, initial_rollback_value_},
    100          {AVB_ATX_PSK_VERSION_LOCATION, initial_rollback_value_}});
    101     std::string metadata_option = "--public_key_metadata=";
    102     metadata_option += kMetadataPath;
    103     GenerateVBMetaImage("vbmeta_a.img",
    104                         "SHA512_RSA4096",
    105                         kNewRollbackValue,
    106                         base::FilePath("test/data/testkey_atx_psk.pem"),
    107                         metadata_option);
    108     SHA256(vbmeta_image_.data(), vbmeta_image_.size(), expected_vbh_extension_);
    109 
    110     ops_.set_expected_public_key(
    111         PublicKeyAVB(base::FilePath("test/data/testkey_atx_psk.pem")));
    112 
    113     AvbSlotVerifyData* slot_data = NULL;
    114     EXPECT_EQ(expected_result_,
    115               avb_atx_slot_verify(ops_.avb_atx_ops(),
    116                                   "_a",
    117                                   lock_state_,
    118                                   slot_state_,
    119                                   oem_data_state_,
    120                                   &slot_data,
    121                                   actual_vbh_extension_));
    122     if (expected_result_ == AVB_SLOT_VERIFY_RESULT_OK) {
    123       EXPECT_NE(nullptr, slot_data);
    124       avb_slot_verify_data_free(slot_data);
    125       // Make sure ATX is being run.
    126       EXPECT_EQ(1, num_atx_calls_);
    127       // Make sure we're hooking set_key_version.
    128       EXPECT_EQ(0, num_key_version_calls_);
    129     }
    130   }
    131 
    132   void CheckVBH() {
    133     if (expected_result_ != AVB_SLOT_VERIFY_RESULT_OK ||
    134         lock_state_ == AVB_ATX_UNLOCKED) {
    135       memset(&expected_vbh_extension_, 0, AVB_SHA256_DIGEST_SIZE);
    136     }
    137     // Check that the VBH was correctly calculated.
    138     EXPECT_EQ(0,
    139               memcmp(actual_vbh_extension_,
    140                      expected_vbh_extension_,
    141                      AVB_SHA256_DIGEST_SIZE));
    142   }
    143 
    144   void CheckNewRollbackState() {
    145     uint64_t expected_rollback_value = kNewRollbackValue;
    146     if (expected_result_ != AVB_SLOT_VERIFY_RESULT_OK ||
    147         lock_state_ == AVB_ATX_UNLOCKED ||
    148         slot_state_ != AVB_ATX_SLOT_MARKED_SUCCESSFUL) {
    149       // Check that rollback indexes were unmodified.
    150       expected_rollback_value = initial_rollback_value_;
    151     }
    152     // Check that all rollback indexes have the expected value.
    153     std::map<size_t, uint64_t> stored_rollback_indexes =
    154         ops_.get_stored_rollback_indexes();
    155     EXPECT_EQ(expected_rollback_value, stored_rollback_indexes[0]);
    156     EXPECT_EQ(expected_rollback_value,
    157               stored_rollback_indexes[AVB_ATX_PIK_VERSION_LOCATION]);
    158     EXPECT_EQ(expected_rollback_value,
    159               stored_rollback_indexes[AVB_ATX_PSK_VERSION_LOCATION]);
    160     // Check that if the rollback did not need to change, there were no writes.
    161     if (initial_rollback_value_ == kNewRollbackValue ||
    162         initial_rollback_value_ == expected_rollback_value) {
    163       EXPECT_EQ(0, num_write_rollback_calls_);
    164     } else {
    165       EXPECT_NE(0, num_write_rollback_calls_);
    166     }
    167   }
    168 
    169  protected:
    170   AvbAtxPermanentAttributes attributes_;
    171   int num_atx_calls_ = 0;
    172   int num_key_version_calls_ = 0;
    173   int num_write_rollback_calls_ = 0;
    174   AvbSlotVerifyResult expected_result_ = AVB_SLOT_VERIFY_RESULT_OK;
    175   uint64_t initial_rollback_value_ = 0;
    176   AvbAtxLockState lock_state_ = AVB_ATX_LOCKED;
    177   AvbAtxSlotState slot_state_ = AVB_ATX_SLOT_MARKED_SUCCESSFUL;
    178   AvbAtxOemDataState oem_data_state_ = AVB_ATX_OEM_DATA_NOT_USED;
    179   uint8_t expected_vbh_extension_[AVB_SHA256_DIGEST_SIZE] = {};
    180   uint8_t actual_vbh_extension_[AVB_SHA256_DIGEST_SIZE] = {};
    181 
    182  private:
    183   void ReadAtxDefaultData() {
    184     std::string tmp;
    185     ASSERT_TRUE(
    186         base::ReadFileToString(base::FilePath(kPermanentAttributesPath), &tmp));
    187     ASSERT_EQ(tmp.size(), sizeof(AvbAtxPermanentAttributes));
    188     memcpy(&attributes_, tmp.data(), tmp.size());
    189   }
    190 };
    191 
    192 TEST_P(AvbAtxSlotVerifyExampleTest, RunWithStartingIndex) {
    193   initial_rollback_value_ = GetParam();
    194   RunSlotVerify();
    195   CheckVBH();
    196   CheckNewRollbackState();
    197 }
    198 
    199 INSTANTIATE_TEST_CASE_P(P,
    200                         AvbAtxSlotVerifyExampleTest,
    201                         ::testing::Values(0,
    202                                           1,
    203                                           kNewRollbackValue / 2,
    204                                           kNewRollbackValue - 1,
    205                                           kNewRollbackValue));
    206 
    207 TEST_F(AvbAtxSlotVerifyExampleTest, RunUnlocked) {
    208   lock_state_ = AVB_ATX_UNLOCKED;
    209   RunSlotVerify();
    210   CheckVBH();
    211   CheckNewRollbackState();
    212 }
    213 
    214 TEST_F(AvbAtxSlotVerifyExampleTest, RunWithSlotNotMarkedSuccessful) {
    215   slot_state_ = AVB_ATX_SLOT_NOT_MARKED_SUCCESSFUL;
    216   RunSlotVerify();
    217   CheckVBH();
    218   CheckNewRollbackState();
    219 }
    220 
    221 TEST_F(AvbAtxSlotVerifyExampleTest, RunWithOemData) {
    222   oem_data_state_ = AVB_ATX_OEM_DATA_USED;
    223   RunSlotVerify();
    224   CheckVBH();
    225   CheckNewRollbackState();
    226 }
    227 
    228 }  // namespace avb
    229