• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SetUp()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.
validate_vbmeta_public_key(AvbOps * ops,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_key_is_trusted)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 
write_rollback_index(AvbOps * ops,size_t rollback_index_slot,uint64_t rollback_index)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 
set_key_version(size_t rollback_index_location,uint64_t key_version)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 
get_random(size_t num_bytes,uint8_t * output)96   AvbIOResult get_random(size_t num_bytes, uint8_t* output) override {
97     return ops_.get_random(num_bytes, output);
98   }
99 
RunSlotVerify()100   void RunSlotVerify() {
101     ops_.set_stored_rollback_indexes(
102         {{0, initial_rollback_value_},
103          {AVB_ATX_PIK_VERSION_LOCATION, initial_rollback_value_},
104          {AVB_ATX_PSK_VERSION_LOCATION, initial_rollback_value_}});
105     std::string metadata_option = "--public_key_metadata=";
106     metadata_option += kMetadataPath;
107     GenerateVBMetaImage("vbmeta_a.img",
108                         "SHA512_RSA4096",
109                         kNewRollbackValue,
110                         base::FilePath("test/data/testkey_atx_psk.pem"),
111                         metadata_option);
112     SHA256(vbmeta_image_.data(), vbmeta_image_.size(), expected_vbh_extension_);
113 
114     ops_.set_expected_public_key(
115         PublicKeyAVB(base::FilePath("test/data/testkey_atx_psk.pem")));
116 
117     AvbSlotVerifyData* slot_data = NULL;
118     EXPECT_EQ(expected_result_,
119               avb_atx_slot_verify(ops_.avb_atx_ops(),
120                                   "_a",
121                                   lock_state_,
122                                   slot_state_,
123                                   oem_data_state_,
124                                   &slot_data,
125                                   actual_vbh_extension_));
126     if (expected_result_ == AVB_SLOT_VERIFY_RESULT_OK) {
127       EXPECT_NE(nullptr, slot_data);
128       avb_slot_verify_data_free(slot_data);
129       // Make sure ATX is being run.
130       EXPECT_EQ(1, num_atx_calls_);
131       // Make sure we're hooking set_key_version.
132       EXPECT_EQ(0, num_key_version_calls_);
133     }
134   }
135 
CheckVBH()136   void CheckVBH() {
137     if (expected_result_ != AVB_SLOT_VERIFY_RESULT_OK ||
138         lock_state_ == AVB_ATX_UNLOCKED) {
139       memset(&expected_vbh_extension_, 0, AVB_SHA256_DIGEST_SIZE);
140     }
141     // Check that the VBH was correctly calculated.
142     EXPECT_EQ(0,
143               memcmp(actual_vbh_extension_,
144                      expected_vbh_extension_,
145                      AVB_SHA256_DIGEST_SIZE));
146   }
147 
CheckNewRollbackState()148   void CheckNewRollbackState() {
149     uint64_t expected_rollback_value = kNewRollbackValue;
150     if (expected_result_ != AVB_SLOT_VERIFY_RESULT_OK ||
151         lock_state_ == AVB_ATX_UNLOCKED ||
152         slot_state_ != AVB_ATX_SLOT_MARKED_SUCCESSFUL) {
153       // Check that rollback indexes were unmodified.
154       expected_rollback_value = initial_rollback_value_;
155     }
156     // Check that all rollback indexes have the expected value.
157     std::map<size_t, uint64_t> stored_rollback_indexes =
158         ops_.get_stored_rollback_indexes();
159     EXPECT_EQ(expected_rollback_value, stored_rollback_indexes[0]);
160     EXPECT_EQ(expected_rollback_value,
161               stored_rollback_indexes[AVB_ATX_PIK_VERSION_LOCATION]);
162     EXPECT_EQ(expected_rollback_value,
163               stored_rollback_indexes[AVB_ATX_PSK_VERSION_LOCATION]);
164     // Check that if the rollback did not need to change, there were no writes.
165     if (initial_rollback_value_ == kNewRollbackValue ||
166         initial_rollback_value_ == expected_rollback_value) {
167       EXPECT_EQ(0, num_write_rollback_calls_);
168     } else {
169       EXPECT_NE(0, num_write_rollback_calls_);
170     }
171   }
172 
173  protected:
174   AvbAtxPermanentAttributes attributes_;
175   int num_atx_calls_ = 0;
176   int num_key_version_calls_ = 0;
177   int num_write_rollback_calls_ = 0;
178   AvbSlotVerifyResult expected_result_ = AVB_SLOT_VERIFY_RESULT_OK;
179   uint64_t initial_rollback_value_ = 0;
180   AvbAtxLockState lock_state_ = AVB_ATX_LOCKED;
181   AvbAtxSlotState slot_state_ = AVB_ATX_SLOT_MARKED_SUCCESSFUL;
182   AvbAtxOemDataState oem_data_state_ = AVB_ATX_OEM_DATA_NOT_USED;
183   uint8_t expected_vbh_extension_[AVB_SHA256_DIGEST_SIZE] = {};
184   uint8_t actual_vbh_extension_[AVB_SHA256_DIGEST_SIZE] = {};
185 
186  private:
ReadAtxDefaultData()187   void ReadAtxDefaultData() {
188     std::string tmp;
189     ASSERT_TRUE(
190         base::ReadFileToString(base::FilePath(kPermanentAttributesPath), &tmp));
191     ASSERT_EQ(tmp.size(), sizeof(AvbAtxPermanentAttributes));
192     memcpy(&attributes_, tmp.data(), tmp.size());
193   }
194 };
195 
TEST_P(AvbAtxSlotVerifyExampleTest,RunWithStartingIndex)196 TEST_P(AvbAtxSlotVerifyExampleTest, RunWithStartingIndex) {
197   initial_rollback_value_ = GetParam();
198   RunSlotVerify();
199   CheckVBH();
200   CheckNewRollbackState();
201 }
202 
203 INSTANTIATE_TEST_CASE_P(P,
204                         AvbAtxSlotVerifyExampleTest,
205                         ::testing::Values(0,
206                                           1,
207                                           kNewRollbackValue / 2,
208                                           kNewRollbackValue - 1,
209                                           kNewRollbackValue));
210 
TEST_F(AvbAtxSlotVerifyExampleTest,RunUnlocked)211 TEST_F(AvbAtxSlotVerifyExampleTest, RunUnlocked) {
212   lock_state_ = AVB_ATX_UNLOCKED;
213   RunSlotVerify();
214   CheckVBH();
215   CheckNewRollbackState();
216 }
217 
TEST_F(AvbAtxSlotVerifyExampleTest,RunWithSlotNotMarkedSuccessful)218 TEST_F(AvbAtxSlotVerifyExampleTest, RunWithSlotNotMarkedSuccessful) {
219   slot_state_ = AVB_ATX_SLOT_NOT_MARKED_SUCCESSFUL;
220   RunSlotVerify();
221   CheckVBH();
222   CheckNewRollbackState();
223 }
224 
TEST_F(AvbAtxSlotVerifyExampleTest,RunWithOemData)225 TEST_F(AvbAtxSlotVerifyExampleTest, RunWithOemData) {
226   oem_data_state_ = AVB_ATX_OEM_DATA_USED;
227   RunSlotVerify();
228   CheckVBH();
229   CheckNewRollbackState();
230 }
231 
232 }  // namespace avb
233