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