blob: a9cd17b1fcd82694c2f6f03e0b0c085d9d4754c4 [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
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070019import os.path
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070020
21import build_image
22import common
23import sparse_img
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070024from rangelib import RangeSet
Tao Bao65b94e92018-10-11 21:57:26 -070025from test_utils import get_testdata_dir, ReleaseToolsTestCase
Tao Bao5fe287b2018-10-11 14:13:52 -070026from verity_utils import (
27 CreateHashtreeInfoGenerator, HashtreeInfo,
28 VerifiedBootVersion1HashtreeInfoGenerator)
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070029
30
Tao Bao65b94e92018-10-11 21:57:26 -070031class VerifiedBootVersion1HashtreeInfoGeneratorTest(ReleaseToolsTestCase):
Tao Bao5fe287b2018-10-11 14:13:52 -070032
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070033 def setUp(self):
Tao Bao65b94e92018-10-11 21:57:26 -070034 self.testdata_dir = get_testdata_dir()
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070035
36 self.partition_size = 1024 * 1024
37 self.prop_dict = {
38 'verity': 'true',
39 'verity_fec': 'true',
40 'system_verity_block_device': '/dev/block/system',
41 'system_size': self.partition_size
42 }
43
44 self.hash_algorithm = "sha256"
45 self.fixed_salt = \
46 "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
47 self.expected_root_hash = \
48 "0b7c4565e87b1026e11fbab91c0bc29e185c847a5b44d40e6e86e461e8adf80d"
49
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070050 def _create_simg(self, raw_data):
51 output_file = common.MakeTempFile()
52 raw_image = common.MakeTempFile()
53 with open(raw_image, 'wb') as f:
54 f.write(raw_data)
55
56 cmd = ["img2simg", raw_image, output_file, '4096']
57 p = common.Run(cmd)
58 p.communicate()
59 self.assertEqual(0, p.returncode)
60
61 return output_file
62
63 def _generate_image(self):
64 partition_size = 1024 * 1024
65 adjusted_size, verity_size = build_image.AdjustPartitionSizeForVerity(
66 partition_size, True)
67
68 raw_image = ""
69 for i in range(adjusted_size):
70 raw_image += str(i % 10)
71
72 output_file = self._create_simg(raw_image)
73
74 # Append the verity metadata.
75 prop_dict = {
76 'partition_size': str(partition_size),
77 'image_size': str(adjusted_size),
78 'verity_block_device': '/dev/block/system',
79 'verity_key': os.path.join(self.testdata_dir, 'testkey'),
80 'verity_signer_cmd': 'verity_signer',
81 'verity_size': str(verity_size),
82 }
83 build_image.MakeVerityEnabledImage(output_file, True, prop_dict)
84
85 return output_file
86
Tao Bao5fe287b2018-10-11 14:13:52 -070087 def test_CreateHashtreeInfoGenerator(self):
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070088 image_file = sparse_img.SparseImage(self._generate_image())
89
Tao Bao5fe287b2018-10-11 14:13:52 -070090 generator = CreateHashtreeInfoGenerator(
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070091 'system', image_file, self.prop_dict)
92 self.assertEqual(
Tao Bao5fe287b2018-10-11 14:13:52 -070093 VerifiedBootVersion1HashtreeInfoGenerator, type(generator))
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070094 self.assertEqual(self.partition_size, generator.partition_size)
95 self.assertTrue(generator.fec_supported)
96
Tao Bao5fe287b2018-10-11 14:13:52 -070097 def test_DecomposeSparseImage(self):
Tianjie Xu67c7cbb2018-08-30 00:32:07 -070098 image_file = sparse_img.SparseImage(self._generate_image())
99
Tao Bao5fe287b2018-10-11 14:13:52 -0700100 generator = VerifiedBootVersion1HashtreeInfoGenerator(
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700101 self.partition_size, 4096, True)
102 generator.DecomposeSparseImage(image_file)
103 self.assertEqual(991232, generator.filesystem_size)
104 self.assertEqual(12288, generator.hashtree_size)
105 self.assertEqual(32768, generator.metadata_size)
106
Tao Bao5fe287b2018-10-11 14:13:52 -0700107 def test_ParseHashtreeMetadata(self):
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700108 image_file = sparse_img.SparseImage(self._generate_image())
Tao Bao5fe287b2018-10-11 14:13:52 -0700109 generator = VerifiedBootVersion1HashtreeInfoGenerator(
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700110 self.partition_size, 4096, True)
111 generator.DecomposeSparseImage(image_file)
112
Tao Bao5fe287b2018-10-11 14:13:52 -0700113 # pylint: disable=protected-access
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700114 generator._ParseHashtreeMetadata()
115
116 self.assertEqual(
117 self.hash_algorithm, generator.hashtree_info.hash_algorithm)
118 self.assertEqual(self.fixed_salt, generator.hashtree_info.salt)
119 self.assertEqual(self.expected_root_hash, generator.hashtree_info.root_hash)
120
Tao Bao5fe287b2018-10-11 14:13:52 -0700121 def test_ValidateHashtree_smoke(self):
122 generator = VerifiedBootVersion1HashtreeInfoGenerator(
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700123 self.partition_size, 4096, True)
124 generator.image = sparse_img.SparseImage(self._generate_image())
125
Tao Bao5fe287b2018-10-11 14:13:52 -0700126 generator.hashtree_info = info = HashtreeInfo()
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700127 info.filesystem_range = RangeSet(data=[0, 991232 / 4096])
128 info.hashtree_range = RangeSet(
129 data=[991232 / 4096, (991232 + 12288) / 4096])
130 info.hash_algorithm = self.hash_algorithm
131 info.salt = self.fixed_salt
132 info.root_hash = self.expected_root_hash
133
134 self.assertTrue(generator.ValidateHashtree())
135
Tao Bao5fe287b2018-10-11 14:13:52 -0700136 def test_ValidateHashtree_failure(self):
137 generator = VerifiedBootVersion1HashtreeInfoGenerator(
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700138 self.partition_size, 4096, True)
139 generator.image = sparse_img.SparseImage(self._generate_image())
140
Tao Bao5fe287b2018-10-11 14:13:52 -0700141 generator.hashtree_info = info = HashtreeInfo()
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700142 info.filesystem_range = RangeSet(data=[0, 991232 / 4096])
143 info.hashtree_range = RangeSet(
144 data=[991232 / 4096, (991232 + 12288) / 4096])
145 info.hash_algorithm = self.hash_algorithm
146 info.salt = self.fixed_salt
147 info.root_hash = "a" + self.expected_root_hash[1:]
148
149 self.assertFalse(generator.ValidateHashtree())
150
Tao Bao5fe287b2018-10-11 14:13:52 -0700151 def test_Generate(self):
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700152 image_file = sparse_img.SparseImage(self._generate_image())
Tao Bao5fe287b2018-10-11 14:13:52 -0700153 generator = CreateHashtreeInfoGenerator('system', 4096, self.prop_dict)
Tianjie Xu67c7cbb2018-08-30 00:32:07 -0700154 info = generator.Generate(image_file)
155
156 self.assertEqual(RangeSet(data=[0, 991232 / 4096]), info.filesystem_range)
157 self.assertEqual(RangeSet(data=[991232 / 4096, (991232 + 12288) / 4096]),
158 info.hashtree_range)
159 self.assertEqual(self.hash_algorithm, info.hash_algorithm)
160 self.assertEqual(self.fixed_salt, info.salt)
161 self.assertEqual(self.expected_root_hash, info.root_hash)