blob: ada70e6d7011eccfc5d814319801cf9b5e0c5537 [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 (
Tianjiebbde59f2021-05-03 21:18:56 -070030 CalculateVbmetaDigest, CreateHashtreeInfoGenerator,
hungweichen17c064d2022-08-18 06:21:49 +000031 CreateVerityImageBuilder, HashtreeInfo)
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070032
Tao Bao7549e5e2018-10-03 14:23:59 -070033BLOCK_SIZE = common.BLOCK_SIZE
34
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070035
Tao Bao7549e5e2018-10-03 14:23:59 -070036class VerifiedBootVersion2VerityImageBuilderTest(ReleaseToolsTestCase):
Tao Bao71197512018-10-11 14:08:45 -070037
Tao Bao4a0d5132018-10-17 22:53:54 -070038 DEFAULT_PROP_DICT = {
39 'partition_size': str(4096 * 1024),
40 'partition_name': 'system',
41 'avb_avbtool': 'avbtool',
42 'avb_hashtree_enable': 'true',
43 'avb_add_hashtree_footer_args': '',
44 }
45
46 def test_init(self):
47 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
48 verity_image_builder = CreateVerityImageBuilder(prop_dict)
49 self.assertIsNotNone(verity_image_builder)
50 self.assertEqual(2, verity_image_builder.version)
51
52 def test_init_MissingProps(self):
53 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
54 del prop_dict['avb_hashtree_enable']
55 verity_image_builder = CreateVerityImageBuilder(prop_dict)
56 self.assertIsNone(verity_image_builder)
57
Tao Bao82490d32019-04-09 00:12:30 -070058 @SkipIfExternalToolsUnavailable()
Tao Bao4a0d5132018-10-17 22:53:54 -070059 def test_Build(self):
60 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
61 verity_image_builder = CreateVerityImageBuilder(prop_dict)
62 self.assertIsNotNone(verity_image_builder)
63 self.assertEqual(2, verity_image_builder.version)
64
65 input_dir = common.MakeTempDir()
66 image_dir = common.MakeTempDir()
67 system_image = os.path.join(image_dir, 'system.img')
68 system_image_size = verity_image_builder.CalculateMaxImageSize()
69 cmd = ['mkuserimg_mke2fs', input_dir, system_image, 'ext4', '/system',
70 str(system_image_size), '-j', '0', '-s']
71 common.RunAndCheckOutput(cmd)
72 verity_image_builder.Build(system_image)
73
74 # Additionally make vbmeta image so that we can verify with avbtool.
75 vbmeta_image = os.path.join(image_dir, 'vbmeta.img')
76 cmd = ['avbtool', 'make_vbmeta_image', '--include_descriptors_from_image',
77 system_image, '--output', vbmeta_image]
78 common.RunAndCheckOutput(cmd)
79
80 # Verify the verity metadata.
81 cmd = ['avbtool', 'verify_image', '--image', vbmeta_image]
82 common.RunAndCheckOutput(cmd)
83
84 def _test_CalculateMinPartitionSize_SetUp(self):
Tao Bao7549e5e2018-10-03 14:23:59 -070085 # To test CalculateMinPartitionSize(), by using 200MB to 2GB image size.
Tao Bao71197512018-10-11 14:08:45 -070086 # - 51200 = 200MB * 1024 * 1024 / 4096
87 # - 524288 = 2GB * 1024 * 1024 * 1024 / 4096
Tao Bao4a0d5132018-10-17 22:53:54 -070088 image_sizes = [BLOCK_SIZE * random.randint(51200, 524288) + offset
89 for offset in range(BLOCK_SIZE)]
Tao Bao71197512018-10-11 14:08:45 -070090
Tao Bao7549e5e2018-10-03 14:23:59 -070091 prop_dict = {
92 'partition_size': None,
93 'partition_name': 'system',
94 'avb_avbtool': 'avbtool',
95 'avb_hashtree_enable': 'true',
96 'avb_add_hashtree_footer_args': None,
97 }
Tao Bao4a0d5132018-10-17 22:53:54 -070098 builder = CreateVerityImageBuilder(prop_dict)
99 self.assertEqual(2, builder.version)
100 return image_sizes, builder
Tao Bao7549e5e2018-10-03 14:23:59 -0700101
102 def test_CalculateMinPartitionSize_LinearFooterSize(self):
Tao Bao71197512018-10-11 14:08:45 -0700103 """Tests with footer size which is linear to partition size."""
Tao Bao4a0d5132018-10-17 22:53:54 -0700104 image_sizes, builder = self._test_CalculateMinPartitionSize_SetUp()
105 for image_size in image_sizes:
Tao Bao71197512018-10-11 14:08:45 -0700106 for ratio in 0.95, 0.56, 0.22:
107 expected_size = common.RoundUpTo4K(int(math.ceil(image_size / ratio)))
108 self.assertEqual(
109 expected_size,
Tao Bao4a0d5132018-10-17 22:53:54 -0700110 builder.CalculateMinPartitionSize(
Tao Bao71197512018-10-11 14:08:45 -0700111 image_size, lambda x, ratio=ratio: int(x * ratio)))
112
113 def test_AVBCalcMinPartitionSize_SlowerGrowthFooterSize(self):
114 """Tests with footer size which grows slower than partition size."""
115
116 def _SizeCalculator(partition_size):
117 """Footer size is the power of 0.95 of partition size."""
118 # Minus footer size to return max image size.
119 return partition_size - int(math.pow(partition_size, 0.95))
120
Tao Bao4a0d5132018-10-17 22:53:54 -0700121 image_sizes, builder = self._test_CalculateMinPartitionSize_SetUp()
122 for image_size in image_sizes:
123 min_partition_size = builder.CalculateMinPartitionSize(
Tao Bao7549e5e2018-10-03 14:23:59 -0700124 image_size, _SizeCalculator)
Tao Bao71197512018-10-11 14:08:45 -0700125 # Checks min_partition_size can accommodate image_size.
126 self.assertGreaterEqual(
127 _SizeCalculator(min_partition_size),
128 image_size)
129 # Checks min_partition_size (round to BLOCK_SIZE) is the minimum.
130 self.assertLess(
131 _SizeCalculator(min_partition_size - BLOCK_SIZE),
132 image_size)
133
Tao Bao7549e5e2018-10-03 14:23:59 -0700134 def test_CalculateMinPartitionSize_FasterGrowthFooterSize(self):
Tao Bao71197512018-10-11 14:08:45 -0700135 """Tests with footer size which grows faster than partition size."""
136
137 def _SizeCalculator(partition_size):
138 """Max image size is the power of 0.95 of partition size."""
139 # Max image size grows less than partition size, which means
140 # footer size grows faster than partition size.
141 return int(math.pow(partition_size, 0.95))
142
Tao Bao4a0d5132018-10-17 22:53:54 -0700143 image_sizes, builder = self._test_CalculateMinPartitionSize_SetUp()
144 for image_size in image_sizes:
145 min_partition_size = builder.CalculateMinPartitionSize(
Tao Bao7549e5e2018-10-03 14:23:59 -0700146 image_size, _SizeCalculator)
Tao Bao71197512018-10-11 14:08:45 -0700147 # Checks min_partition_size can accommodate image_size.
148 self.assertGreaterEqual(
149 _SizeCalculator(min_partition_size),
150 image_size)
151 # Checks min_partition_size (round to BLOCK_SIZE) is the minimum.
152 self.assertLess(
153 _SizeCalculator(min_partition_size - BLOCK_SIZE),
154 image_size)
Tianjiebbde59f2021-05-03 21:18:56 -0700155
156 @SkipIfExternalToolsUnavailable()
157 def test_CalculateVbmetaDigest(self):
158 prop_dict = copy.deepcopy(self.DEFAULT_PROP_DICT)
159 verity_image_builder = CreateVerityImageBuilder(prop_dict)
160 self.assertEqual(2, verity_image_builder.version)
161
162 input_dir = common.MakeTempDir()
163 image_dir = common.MakeTempDir()
164 os.mkdir(os.path.join(image_dir, 'IMAGES'))
165 system_image = os.path.join(image_dir, 'IMAGES', 'system.img')
166 system_image_size = verity_image_builder.CalculateMaxImageSize()
167 cmd = ['mkuserimg_mke2fs', input_dir, system_image, 'ext4', '/system',
168 str(system_image_size), '-j', '0', '-s']
169 common.RunAndCheckOutput(cmd)
170 verity_image_builder.Build(system_image)
171
172 # Additionally make vbmeta image
173 vbmeta_image = os.path.join(image_dir, 'IMAGES', 'vbmeta.img')
174 cmd = ['avbtool', 'make_vbmeta_image', '--include_descriptors_from_image',
175 system_image, '--output', vbmeta_image]
176 common.RunAndCheckOutput(cmd)
177
178 # Verify the verity metadata.
179 cmd = ['avbtool', 'verify_image', '--image', vbmeta_image]
180 common.RunAndCheckOutput(cmd)
181 digest = CalculateVbmetaDigest(image_dir, 'avbtool')
182 self.assertIsNotNone(digest)