blob: 580612fadfcb4fd6dad3e3fb060e7cca09aa9776 [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
19from __future__ import print_function
20
21import os
22import os.path
23import unittest
24
25import build_image
26import common
27import sparse_img
28import test_utils
29import verity_utils
30from rangelib import RangeSet
31
32
33class VerityUtilsTest(unittest.TestCase):
34 def setUp(self):
35 self.testdata_dir = test_utils.get_testdata_dir()
36
37 self.partition_size = 1024 * 1024
38 self.prop_dict = {
39 'verity': 'true',
40 'verity_fec': 'true',
41 'system_verity_block_device': '/dev/block/system',
42 'system_size': self.partition_size
43 }
44
45 self.hash_algorithm = "sha256"
46 self.fixed_salt = \
47 "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
48 self.expected_root_hash = \
49 "0b7c4565e87b1026e11fbab91c0bc29e185c847a5b44d40e6e86e461e8adf80d"
50
51 def tearDown(self):
52 common.Cleanup()
53
54 def _create_simg(self, raw_data):
55 output_file = common.MakeTempFile()
56 raw_image = common.MakeTempFile()
57 with open(raw_image, 'wb') as f:
58 f.write(raw_data)
59
60 cmd = ["img2simg", raw_image, output_file, '4096']
61 p = common.Run(cmd)
62 p.communicate()
63 self.assertEqual(0, p.returncode)
64
65 return output_file
66
67 def _generate_image(self):
68 partition_size = 1024 * 1024
69 adjusted_size, verity_size = build_image.AdjustPartitionSizeForVerity(
70 partition_size, True)
71
72 raw_image = ""
73 for i in range(adjusted_size):
74 raw_image += str(i % 10)
75
76 output_file = self._create_simg(raw_image)
77
78 # Append the verity metadata.
79 prop_dict = {
80 'partition_size': str(partition_size),
81 'image_size': str(adjusted_size),
82 'verity_block_device': '/dev/block/system',
83 'verity_key': os.path.join(self.testdata_dir, 'testkey'),
84 'verity_signer_cmd': 'verity_signer',
85 'verity_size': str(verity_size),
86 }
87 build_image.MakeVerityEnabledImage(output_file, True, prop_dict)
88
89 return output_file
90
91 def test_VerifiedBootVersion1HashtreeInfoGenerator_create(self):
92 image_file = sparse_img.SparseImage(self._generate_image())
93
94 generator = verity_utils.CreateHashtreeInfoGenerator(
95 'system', image_file, self.prop_dict)
96 self.assertEqual(
97 verity_utils.VerifiedBootVersion1HashtreeInfoGenerator, type(generator))
98 self.assertEqual(self.partition_size, generator.partition_size)
99 self.assertTrue(generator.fec_supported)
100
101 def test_VerifiedBootVersion1HashtreeInfoGenerator_decomposeImage(self):
102 image_file = sparse_img.SparseImage(self._generate_image())
103
104 generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
105 self.partition_size, 4096, True)
106 generator.DecomposeSparseImage(image_file)
107 self.assertEqual(991232, generator.filesystem_size)
108 self.assertEqual(12288, generator.hashtree_size)
109 self.assertEqual(32768, generator.metadata_size)
110
111 def test_VerifiedBootVersion1HashtreeInfoGenerator_parseHashtreeMetadata(
112 self):
113 image_file = sparse_img.SparseImage(self._generate_image())
114 generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
115 self.partition_size, 4096, True)
116 generator.DecomposeSparseImage(image_file)
117
118 generator._ParseHashtreeMetadata()
119
120 self.assertEqual(
121 self.hash_algorithm, generator.hashtree_info.hash_algorithm)
122 self.assertEqual(self.fixed_salt, generator.hashtree_info.salt)
123 self.assertEqual(self.expected_root_hash, generator.hashtree_info.root_hash)
124
125 def test_VerifiedBootVersion1HashtreeInfoGenerator_validateHashtree_smoke(
126 self):
127 generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
128 self.partition_size, 4096, True)
129 generator.image = sparse_img.SparseImage(self._generate_image())
130
131 generator.hashtree_info = info = verity_utils.HashtreeInfo()
132 info.filesystem_range = RangeSet(data=[0, 991232 / 4096])
133 info.hashtree_range = RangeSet(
134 data=[991232 / 4096, (991232 + 12288) / 4096])
135 info.hash_algorithm = self.hash_algorithm
136 info.salt = self.fixed_salt
137 info.root_hash = self.expected_root_hash
138
139 self.assertTrue(generator.ValidateHashtree())
140
141 def test_VerifiedBootVersion1HashtreeInfoGenerator_validateHashtree_failure(
142 self):
143 generator = verity_utils.VerifiedBootVersion1HashtreeInfoGenerator(
144 self.partition_size, 4096, True)
145 generator.image = sparse_img.SparseImage(self._generate_image())
146
147 generator.hashtree_info = info = verity_utils.HashtreeInfo()
148 info.filesystem_range = RangeSet(data=[0, 991232 / 4096])
149 info.hashtree_range = RangeSet(
150 data=[991232 / 4096, (991232 + 12288) / 4096])
151 info.hash_algorithm = self.hash_algorithm
152 info.salt = self.fixed_salt
153 info.root_hash = "a" + self.expected_root_hash[1:]
154
155 self.assertFalse(generator.ValidateHashtree())
156
157 def test_VerifiedBootVersion1HashtreeInfoGenerator_generate(self):
158 image_file = sparse_img.SparseImage(self._generate_image())
159 generator = verity_utils.CreateHashtreeInfoGenerator(
160 'system', 4096, self.prop_dict)
161 info = generator.Generate(image_file)
162
163 self.assertEqual(RangeSet(data=[0, 991232 / 4096]), info.filesystem_range)
164 self.assertEqual(RangeSet(data=[991232 / 4096, (991232 + 12288) / 4096]),
165 info.hashtree_range)
166 self.assertEqual(self.hash_algorithm, info.hash_algorithm)
167 self.assertEqual(self.fixed_salt, info.salt)
168 self.assertEqual(self.expected_root_hash, info.root_hash)