blob: 4a0ff0981dadd74a1e0fd9443e287e115929697c [file] [log] [blame]
Tianjie Xu67c7cbb2018-08-30 00:32:07 -07001#
2# Copyright (C) 2018 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"""Unittests for verity_utils.py."""
18
Tao Bao4a0d5132018-10-17 22:53:54 -070019import copy
Tao Bao71197512018-10-11 14:08:45 -070020import math
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070021import os.path
Tao Bao71197512018-10-11 14:08:45 -070022import random
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070023
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070024import common
25import sparse_img
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070026from rangelib import RangeSet
Tao Bao82490d32019-04-09 00:12:30 -070027from test_utils import (
28 get_testdata_dir, ReleaseToolsTestCase, SkipIfExternalToolsUnavailable)
Tao Bao5fe287b2018-10-11 14:13:52 -070029from verity_utils import (
hungweichencc9c05d2022-08-23 05:45:42 +000030 CalculateVbmetaDigest, CreateVerityImageBuilder)
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070031
Tao Bao7549e5e2018-10-03 14:23:59 -070032BLOCK_SIZE = common.BLOCK_SIZE
33
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070034
Tao Bao7549e5e2018-10-03 14:23:59 -070035class VerifiedBootVersion2VerityImageBuilderTest(ReleaseToolsTestCase):
Tao Bao71197512018-10-11 14:08:45 -070036
Tao Bao4a0d5132018-10-17 22:53:54 -070037 DEFAULT_PROP_DICT = {
38 'partition_size': str(4096 * 1024),
39 'partition_name': 'system',
40 'avb_avbtool': 'avbtool',
41 'avb_hashtree_enable': 'true',
42 'avb_add_hashtree_footer_args': '',
43 }
44
45 def test_init(self):
46 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
47 verity_image_builder = CreateVerityImageBuilder(prop_dict)
48 self.assertIsNotNone(verity_image_builder)
49 self.assertEqual(2, verity_image_builder.version)
50
51 def test_init_MissingProps(self):
52 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
53 del prop_dict['avb_hashtree_enable']
54 verity_image_builder = CreateVerityImageBuilder(prop_dict)
55 self.assertIsNone(verity_image_builder)
56
Tao Bao82490d32019-04-09 00:12:30 -070057 @SkipIfExternalToolsUnavailable()
Tao Bao4a0d5132018-10-17 22:53:54 -070058 def test_Build(self):
59 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
60 verity_image_builder = CreateVerityImageBuilder(prop_dict)
61 self.assertIsNotNone(verity_image_builder)
62 self.assertEqual(2, verity_image_builder.version)
63
64 input_dir = common.MakeTempDir()
65 image_dir = common.MakeTempDir()
66 system_image = os.path.join(image_dir, 'system.img')
67 system_image_size = verity_image_builder.CalculateMaxImageSize()
68 cmd = ['mkuserimg_mke2fs', input_dir, system_image, 'ext4', '/system',
69 str(system_image_size), '-j', '0', '-s']
70 common.RunAndCheckOutput(cmd)
71 verity_image_builder.Build(system_image)
72
73 # Additionally make vbmeta image so that we can verify with avbtool.
74 vbmeta_image = os.path.join(image_dir, 'vbmeta.img')
75 cmd = ['avbtool', 'make_vbmeta_image', '--include_descriptors_from_image',
76 system_image, '--output', vbmeta_image]
77 common.RunAndCheckOutput(cmd)
78
79 # Verify the verity metadata.
80 cmd = ['avbtool', 'verify_image', '--image', vbmeta_image]
81 common.RunAndCheckOutput(cmd)
82
83 def _test_CalculateMinPartitionSize_SetUp(self):
Tao Bao7549e5e2018-10-03 14:23:59 -070084 # To test CalculateMinPartitionSize(), by using 200MB to 2GB image size.
Tao Bao71197512018-10-11 14:08:45 -070085 # - 51200 = 200MB * 1024 * 1024 / 4096
86 # - 524288 = 2GB * 1024 * 1024 * 1024 / 4096
Tao Bao4a0d5132018-10-17 22:53:54 -070087 image_sizes = [BLOCK_SIZE * random.randint(51200, 524288) + offset
88 for offset in range(BLOCK_SIZE)]
Tao Bao71197512018-10-11 14:08:45 -070089
Tao Bao7549e5e2018-10-03 14:23:59 -070090 prop_dict = {
91 'partition_size': None,
92 'partition_name': 'system',
93 'avb_avbtool': 'avbtool',
94 'avb_hashtree_enable': 'true',
95 'avb_add_hashtree_footer_args': None,
96 }
Tao Bao4a0d5132018-10-17 22:53:54 -070097 builder = CreateVerityImageBuilder(prop_dict)
98 self.assertEqual(2, builder.version)
99 return image_sizes, builder
Tao Bao7549e5e2018-10-03 14:23:59 -0700100
101 def test_CalculateMinPartitionSize_LinearFooterSize(self):
Tao Bao71197512018-10-11 14:08:45 -0700102 """Tests with footer size which is linear to partition size."""
Tao Bao4a0d5132018-10-17 22:53:54 -0700103 image_sizes, builder = self._test_CalculateMinPartitionSize_SetUp()
104 for image_size in image_sizes:
Tao Bao71197512018-10-11 14:08:45 -0700105 for ratio in 0.95, 0.56, 0.22:
106 expected_size = common.RoundUpTo4K(int(math.ceil(image_size / ratio)))
107 self.assertEqual(
108 expected_size,
Tao Bao4a0d5132018-10-17 22:53:54 -0700109 builder.CalculateMinPartitionSize(
Tao Bao71197512018-10-11 14:08:45 -0700110 image_size, lambda x, ratio=ratio: int(x * ratio)))
111
112 def test_AVBCalcMinPartitionSize_SlowerGrowthFooterSize(self):
113 """Tests with footer size which grows slower than partition size."""
114
115 def _SizeCalculator(partition_size):
116 """Footer size is the power of 0.95 of partition size."""
117 # Minus footer size to return max image size.
118 return partition_size - int(math.pow(partition_size, 0.95))
119
Tao Bao4a0d5132018-10-17 22:53:54 -0700120 image_sizes, builder = self._test_CalculateMinPartitionSize_SetUp()
121 for image_size in image_sizes:
122 min_partition_size = builder.CalculateMinPartitionSize(
Tao Bao7549e5e2018-10-03 14:23:59 -0700123 image_size, _SizeCalculator)
Tao Bao71197512018-10-11 14:08:45 -0700124 # Checks min_partition_size can accommodate image_size.
125 self.assertGreaterEqual(
126 _SizeCalculator(min_partition_size),
127 image_size)
128 # Checks min_partition_size (round to BLOCK_SIZE) is the minimum.
129 self.assertLess(
130 _SizeCalculator(min_partition_size - BLOCK_SIZE),
131 image_size)
132
Tao Bao7549e5e2018-10-03 14:23:59 -0700133 def test_CalculateMinPartitionSize_FasterGrowthFooterSize(self):
Tao Bao71197512018-10-11 14:08:45 -0700134 """Tests with footer size which grows faster than partition size."""
135
136 def _SizeCalculator(partition_size):
137 """Max image size is the power of 0.95 of partition size."""
138 # Max image size grows less than partition size, which means
139 # footer size grows faster than partition size.
140 return int(math.pow(partition_size, 0.95))
141
Tao Bao4a0d5132018-10-17 22:53:54 -0700142 image_sizes, builder = self._test_CalculateMinPartitionSize_SetUp()
143 for image_size in image_sizes:
144 min_partition_size = builder.CalculateMinPartitionSize(
Tao Bao7549e5e2018-10-03 14:23:59 -0700145 image_size, _SizeCalculator)
Tao Bao71197512018-10-11 14:08:45 -0700146 # Checks min_partition_size can accommodate image_size.
147 self.assertGreaterEqual(
148 _SizeCalculator(min_partition_size),
149 image_size)
150 # Checks min_partition_size (round to BLOCK_SIZE) is the minimum.
151 self.assertLess(
152 _SizeCalculator(min_partition_size - BLOCK_SIZE),
153 image_size)
Tianjiebbde59f2021-05-03 21:18:56 -0700154
155 @SkipIfExternalToolsUnavailable()
156 def test_CalculateVbmetaDigest(self):
157 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
158 verity_image_builder = CreateVerityImageBuilder(prop_dict)
159 self.assertEqual(2, verity_image_builder.version)
160
161 input_dir = common.MakeTempDir()
162 image_dir = common.MakeTempDir()
163 os.mkdir(os.path.join(image_dir, 'IMAGES'))
164 system_image = os.path.join(image_dir, 'IMAGES', 'system.img')
165 system_image_size = verity_image_builder.CalculateMaxImageSize()
166 cmd = ['mkuserimg_mke2fs', input_dir, system_image, 'ext4', '/system',
167 str(system_image_size), '-j', '0', '-s']
168 common.RunAndCheckOutput(cmd)
169 verity_image_builder.Build(system_image)
170
171 # Additionally make vbmeta image
172 vbmeta_image = os.path.join(image_dir, 'IMAGES', 'vbmeta.img')
173 cmd = ['avbtool', 'make_vbmeta_image', '--include_descriptors_from_image',
174 system_image, '--output', vbmeta_image]
175 common.RunAndCheckOutput(cmd)
176
177 # Verify the verity metadata.
178 cmd = ['avbtool', 'verify_image', '--image', vbmeta_image]
179 common.RunAndCheckOutput(cmd)
180 digest = CalculateVbmetaDigest(image_dir, 'avbtool')
181 self.assertIsNotNone(digest)