xref: /aosp_15_r20/external/avb/test/avb_cert_slot_verify_unittest.cc (revision d289c2ba6de359471b23d594623b906876bc48a0)
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 "examples/cert/avb_cert_slot_verify.h"
26 
27 #include <base/files/file_util.h>
28 #include <gtest/gtest.h>
29 #include <openssl/sha.h>
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include "avb_unittest_util.h"
34 #include "fake_avb_ops.h"
35 
36 namespace {
37 
38 const char kMetadataPath[] = "test/data/cert_metadata.bin";
39 const char kPermanentAttributesPath[] =
40     "test/data/cert_permanent_attributes.bin";
41 const uint64_t kNewRollbackValue = 42;
42 
43 } /* namespace */
44 
45 namespace avb {
46 
47 // A fixture for testing avb_cert_slot_verify() with libavb_cert. This test is
48 // parameterized on the initial stored rollback index (same value used in all
49 // relevant locations).
50 class AvbCertSlotVerifyExampleTest
51     : public BaseAvbToolTest,
52       public FakeAvbOpsDelegateWithDefaults,
53       public ::testing::WithParamInterface<uint64_t> {
54  public:
55   ~AvbCertSlotVerifyExampleTest() override = default;
56 
SetUp()57   void SetUp() override {
58     BaseAvbToolTest::SetUp();
59     ReadCertDefaultData();
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 libavb_cert implementation.
74     ++num_cert_calls_;
75     return avb_cert_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_CERT_PIK_VERSION_LOCATION, initial_rollback_value_},
104          {AVB_CERT_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                         "test/data/testkey_cert_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("test/data/testkey_cert_psk.pem"));
116 
117     AvbSlotVerifyData* slot_data = NULL;
118     EXPECT_EQ(expected_result_,
119               avb_cert_slot_verify(ops_.avb_cert_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 libavb_cert is being run.
130       EXPECT_EQ(1, num_cert_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_CERT_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_CERT_UNLOCKED ||
152         slot_state_ != AVB_CERT_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_CERT_PIK_VERSION_LOCATION]);
162     EXPECT_EQ(expected_rollback_value,
163               stored_rollback_indexes[AVB_CERT_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   AvbCertPermanentAttributes attributes_;
175   int num_cert_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   AvbCertLockState lock_state_ = AVB_CERT_LOCKED;
181   AvbCertSlotState slot_state_ = AVB_CERT_SLOT_MARKED_SUCCESSFUL;
182   AvbCertOemDataState oem_data_state_ = AVB_CERT_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:
ReadCertDefaultData()187   void ReadCertDefaultData() {
188     std::string tmp;
189     ASSERT_TRUE(
190         base::ReadFileToString(base::FilePath(kPermanentAttributesPath), &tmp));
191     ASSERT_EQ(tmp.size(), sizeof(AvbCertPermanentAttributes));
192     memcpy(&attributes_, tmp.data(), tmp.size());
193   }
194 };
195 
TEST_P(AvbCertSlotVerifyExampleTest,RunWithStartingIndex)196 TEST_P(AvbCertSlotVerifyExampleTest, RunWithStartingIndex) {
197   initial_rollback_value_ = GetParam();
198   RunSlotVerify();
199   CheckVBH();
200   CheckNewRollbackState();
201 }
202 
203 INSTANTIATE_TEST_CASE_P(P,
204                         AvbCertSlotVerifyExampleTest,
205                         ::testing::Values(0,
206                                           1,
207                                           kNewRollbackValue / 2,
208                                           kNewRollbackValue - 1,
209                                           kNewRollbackValue));
210 
TEST_F(AvbCertSlotVerifyExampleTest,RunUnlocked)211 TEST_F(AvbCertSlotVerifyExampleTest, RunUnlocked) {
212   lock_state_ = AVB_CERT_UNLOCKED;
213   RunSlotVerify();
214   CheckVBH();
215   CheckNewRollbackState();
216 }
217 
TEST_F(AvbCertSlotVerifyExampleTest,RunWithSlotNotMarkedSuccessful)218 TEST_F(AvbCertSlotVerifyExampleTest, RunWithSlotNotMarkedSuccessful) {
219   slot_state_ = AVB_CERT_SLOT_NOT_MARKED_SUCCESSFUL;
220   RunSlotVerify();
221   CheckVBH();
222   CheckNewRollbackState();
223 }
224 
TEST_F(AvbCertSlotVerifyExampleTest,RunWithOemData)225 TEST_F(AvbCertSlotVerifyExampleTest, RunWithOemData) {
226   oem_data_state_ = AVB_CERT_OEM_DATA_USED;
227   RunSlotVerify();
228   CheckVBH();
229   CheckNewRollbackState();
230 }
231 
232 }  // namespace avb
233