blob: 7d8b80d26fc3354c663e7fb41d7e6b1dba626a17 [file] [log] [blame]
David Zeuthen21e95262016-07-27 17:58:40 -04001/*
2 * Copyright (C) 2016 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#include <iostream>
18
19#include <endian.h>
20#include <inttypes.h>
21#include <string.h>
22
23#include <base/files/file_util.h>
24#include <base/strings/string_util.h>
25#include <base/strings/stringprintf.h>
26
27#include "avb_unittest_util.h"
28#include "libavb.h"
29
30class VerifyTest : public BaseAvbToolTest {
31 public:
32 VerifyTest() {}
33
34 protected:
35 // Helper function for ModificationDetection test. Modifies
36 // boot_image_ in a number of places in the sub-array at |offset| of
37 // size |length| and checks that avb_vbmeta_image_verify() returns
38 // |expected_result|.
39 bool test_modification(AvbVBMetaVerifyResult expected_result, size_t offset,
40 size_t length);
41};
42
43TEST_F(VerifyTest, BootImageStructSize) {
44 EXPECT_EQ(256UL, sizeof(AvbVBMetaImageHeader));
45}
46
47TEST_F(VerifyTest, CheckSHA256RSA2048) {
48 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
49 base::FilePath("test/data/testkey_rsa2048.pem"));
50 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
51 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
52 NULL, NULL));
53}
54
55TEST_F(VerifyTest, CheckSHA256RSA4096) {
56 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA4096", 0,
57 base::FilePath("test/data/testkey_rsa4096.pem"));
58 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
59 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
60 NULL, NULL));
61}
62
63TEST_F(VerifyTest, CheckSHA256RSA8192) {
64 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0,
65 base::FilePath("test/data/testkey_rsa8192.pem"));
66 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
67 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
68 NULL, NULL));
69}
70
71TEST_F(VerifyTest, CheckSHA512RSA2048) {
72 GenerateVBMetaImage("vbmeta.img", "SHA512_RSA2048", 0,
73 base::FilePath("test/data/testkey_rsa2048.pem"));
74 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
75 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
76 NULL, NULL));
77}
78
79TEST_F(VerifyTest, CheckSHA512RSA4096) {
80 GenerateVBMetaImage("vbmeta.img", "SHA512_RSA4096", 0,
81 base::FilePath("test/data/testkey_rsa4096.pem"));
82 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
83 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
84 NULL, NULL));
85}
86
87TEST_F(VerifyTest, CheckSHA512RSA8192) {
88 GenerateVBMetaImage("vbmeta.img", "SHA512_RSA8192", 0,
89 base::FilePath("test/data/testkey_rsa8192.pem"));
90 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
91 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
92 NULL, NULL));
93}
94
95TEST_F(VerifyTest, CheckUnsigned) {
96 GenerateVBMetaImage("vbmeta.img", "", 0, base::FilePath(""));
97 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED,
98 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
99 NULL, NULL));
100}
101
102TEST_F(VerifyTest, CheckBiggerLength) {
103 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
104 base::FilePath("test/data/testkey_rsa2048.pem"));
105 // Check that it's OK if we pass a bigger length than what the
106 // header indicates.
107 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
108 avb_vbmeta_image_verify(vbmeta_image_.data(),
109 vbmeta_image_.size() + 8192, NULL, NULL));
110}
111
112TEST_F(VerifyTest, BadMagic) {
113 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
114 base::FilePath("test/data/testkey_rsa2048.pem"));
115 vbmeta_image_[0] = 'Z';
116 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
117 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
118 NULL, NULL));
119}
120
121TEST_F(VerifyTest, MajorVersionCheck) {
122 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
123 base::FilePath("test/data/testkey_rsa2048.pem"));
124
125 AvbVBMetaImageHeader *h =
126 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
127 h->header_version_major = htobe32(1 + be32toh(h->header_version_major));
128 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
129 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
130 NULL, NULL));
131}
132
133TEST_F(VerifyTest, MinorVersionCheck) {
134 GenerateVBMetaImage("vbmeta.img", "", 0, base::FilePath(""));
135
136 AvbVBMetaImageHeader *h =
137 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
138 h->header_version_minor = htobe32(1 + be32toh(h->header_version_minor));
139 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED,
140 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
141 NULL, NULL));
142}
143
144TEST_F(VerifyTest, BlockSizesAddUpToLessThanLength) {
145 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
146 base::FilePath("test/data/testkey_rsa2048.pem"));
147
148 AvbVBMetaImageHeader *h =
149 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
150 AvbVBMetaImageHeader backup = *h;
151
152 // Check that the sum of the two block lengths is less than passed
153 // in size. Use a size that's a multiple of 64 to avoid failure on
154 // earlier check.
155 uint64_t size = vbmeta_image_.size() & (~0x3f);
156
157 h->authentication_data_block_size = htobe64(size);
158 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
159 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
160 NULL, NULL));
161 *h = backup;
162
163 h->auxiliary_data_block_size = htobe64(size);
164 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
165 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
166 NULL, NULL));
167 *h = backup;
168
169 // Overflow checks - choose overflow candidate so it's a multiple of
170 // 64 otherwise we'll fail on an earlier check.
171 size = 0xffffffffffffffc0UL;
172
173 h->authentication_data_block_size = htobe64(size);
174 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
175 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
176 NULL, NULL));
177 *h = backup;
178
179 h->auxiliary_data_block_size = htobe64(size);
180 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
181 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
182 NULL, NULL));
183 *h = backup;
184
185 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
186 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
187 NULL, NULL));
188}
189
190TEST_F(VerifyTest, BlockSizesMultipleOf64) {
191 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
192 base::FilePath("test/data/testkey_rsa2048.pem"));
193
194 AvbVBMetaImageHeader *h =
195 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
196 AvbVBMetaImageHeader backup = *h;
197
198 h->authentication_data_block_size =
199 htobe32(be32toh(h->authentication_data_block_size) - 32);
200 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
201 avb_vbmeta_image_verify(vbmeta_image_.data(),
202 vbmeta_image_.size() - 32, NULL, NULL));
203 *h = backup;
204
205 h->auxiliary_data_block_size =
206 htobe32(be32toh(h->auxiliary_data_block_size) - 32);
207 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
208 avb_vbmeta_image_verify(vbmeta_image_.data(),
209 vbmeta_image_.size() - 32, NULL, NULL));
210 *h = backup;
211
212 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
213 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
214 NULL, NULL));
215}
216
217TEST_F(VerifyTest, HashOutOfBounds) {
218 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
219 base::FilePath("test/data/testkey_rsa2048.pem"));
220
221 AvbVBMetaImageHeader *h =
222 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
223
224 // Check we catch when hash data goes out of bounds.
225 h->hash_offset = htobe64(4);
226 h->hash_size = htobe64(be64toh(h->authentication_data_block_size));
227 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
228 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
229 NULL, NULL));
230
231 // Overflow checks.
232 h->hash_offset = htobe64(4);
233 h->hash_size = htobe64(0xfffffffffffffffeUL);
234 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
235 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
236 NULL, NULL));
237}
238
239TEST_F(VerifyTest, SignatureOutOfBounds) {
240 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
241 base::FilePath("test/data/testkey_rsa2048.pem"));
242
243 AvbVBMetaImageHeader *h =
244 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
245
246 // Check we catch when signature data goes out of bounds.
247 h->signature_offset = htobe64(4);
248 h->signature_size = htobe64(be64toh(h->authentication_data_block_size));
249 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
250 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
251 NULL, NULL));
252
253 // Overflow checks.
254 h->signature_offset = htobe64(4);
255 h->signature_size = htobe64(0xfffffffffffffffeUL);
256 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
257 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
258 NULL, NULL));
259}
260
261TEST_F(VerifyTest, PublicKeyOutOfBounds) {
262 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
263 base::FilePath("test/data/testkey_rsa2048.pem"));
264
265 AvbVBMetaImageHeader *h =
266 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
267
268 // Check we catch when public key data goes out of bounds.
269 h->public_key_offset = htobe64(4);
270 h->public_key_size = htobe64(be64toh(h->auxiliary_data_block_size));
271 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
272 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
273 NULL, NULL));
274
275 // Overflow checks.
276 h->public_key_offset = htobe64(4);
277 h->public_key_size = htobe64(0xfffffffffffffffeUL);
278 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
279 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
280 NULL, NULL));
281}
282
283TEST_F(VerifyTest, InvalidAlgorithmField) {
284 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
285 base::FilePath("test/data/testkey_rsa2048.pem"));
286
287 AvbVBMetaImageHeader *h =
288 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
289 AvbVBMetaImageHeader backup = *h;
290
291 // Check we bail on unknown algorithm.
292 h->algorithm_type = htobe32(_AVB_ALGORITHM_NUM_TYPES);
293 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
294 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
295 NULL, NULL));
296 *h = backup;
297 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
298 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
299 NULL, NULL));
300}
301
302TEST_F(VerifyTest, PublicKeyBlockTooSmall) {
303 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
304 base::FilePath("test/data/testkey_rsa2048.pem"));
305
306 AvbVBMetaImageHeader *h =
307 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data());
308 AvbVBMetaImageHeader backup = *h;
309
310 // Check we bail if the auxiliary data block is too small.
311 uint64_t change = be64toh(h->auxiliary_data_block_size) - 64;
312 h->auxiliary_data_block_size = htobe64(change);
313 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
314 avb_vbmeta_image_verify(vbmeta_image_.data(),
315 vbmeta_image_.size() - change, NULL, NULL));
316 *h = backup;
317 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
318 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
319 NULL, NULL));
320}
321
322bool VerifyTest::test_modification(AvbVBMetaVerifyResult expected_result,
323 size_t offset, size_t length) {
324 uint8_t *d = reinterpret_cast<uint8_t *>(vbmeta_image_.data());
325 const int kNumCheckpoints = 16;
326
327 // Test |kNumCheckpoints| modifications in the start, middle, and
328 // end of given sub-array.
329 for (int n = 0; n <= kNumCheckpoints; n++) {
330 size_t o = std::min(length * n / kNumCheckpoints, length - 1) + offset;
331 d[o] ^= 0x80;
332 AvbVBMetaVerifyResult result = avb_vbmeta_image_verify(
333 vbmeta_image_.data(), vbmeta_image_.size(), NULL, NULL);
334 d[o] ^= 0x80;
335 if (result != expected_result) return false;
336 }
337
338 return true;
339}
340
341TEST_F(VerifyTest, ModificationDetection) {
342 GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0,
343 base::FilePath("test/data/testkey_rsa2048.pem"));
344
345 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
346 avb_vbmeta_image_verify(vbmeta_image_.data(), vbmeta_image_.size(),
347 NULL, NULL));
348
349 AvbVBMetaImageHeader h;
350 avb_vbmeta_image_header_to_host_byte_order(
351 reinterpret_cast<AvbVBMetaImageHeader *>(vbmeta_image_.data()), &h);
352
353 size_t header_block_offset = 0;
354 size_t authentication_block_offset =
355 header_block_offset + sizeof(AvbVBMetaImageHeader);
356 size_t auxiliary_block_offset =
357 authentication_block_offset + h.authentication_data_block_size;
358
359 // Ensure we detect modification of the header data block. Do this
360 // in a field that's not validated so INVALID_VBMETA_HEADER
361 // isn't returned.
362 EXPECT_TRUE(test_modification(
363 AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH,
364 offsetof(AvbVBMetaImageHeader, reserved),
365 sizeof(AvbVBMetaImageHeader) - offsetof(AvbVBMetaImageHeader, reserved)));
366 // Also check the |reserved| field.
367 EXPECT_TRUE(test_modification(AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH,
368 offsetof(AvbVBMetaImageHeader, reserved),
369 sizeof(AvbVBMetaImageHeader().reserved)));
370
371 // Ensure we detect modifications in the auxiliary data block.
372 EXPECT_TRUE(test_modification(AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH,
373 auxiliary_block_offset,
374 h.auxiliary_data_block_size));
375
376 // Modifications in the hash part of the Authentication data block
377 // should also yield HASH_MISMATCH. This is because the hash check
378 // compares the calculated hash against the stored hash.
379 EXPECT_TRUE(test_modification(AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH,
380 authentication_block_offset + h.hash_offset,
381 h.hash_size));
382
383 // Modifications in the signature part of the Authentication data
384 // block, should not cause a hash mismatch ... but will cause a
385 // signature mismatch.
386 EXPECT_TRUE(test_modification(
387 AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH,
388 authentication_block_offset + h.signature_offset, h.signature_size));
389
390 // Mofications outside the hash and signature parts of the
391 // Authentication data block are not detected. This is because it's
392 // not part of the hash calculation.
393 uint64_t offset = h.signature_offset + h.signature_size;
394 ASSERT_LT(h.hash_offset, h.signature_offset);
395 ASSERT_LT(offset + 1, h.authentication_data_block_size);
396 EXPECT_TRUE(test_modification(AVB_VBMETA_VERIFY_RESULT_OK,
397 authentication_block_offset + offset,
398 h.authentication_data_block_size - offset));
399}
400
401TEST_F(VerifyTest, VBMetaHeaderByteswap) {
402 AvbVBMetaImageHeader h;
403 AvbVBMetaImageHeader s;
404 uint32_t n32;
405 uint64_t n64;
406
407 n32 = 0x11223344;
408 n64 = 0x1122334455667788;
409
410 h.header_version_major = htobe32(n32);
411 n32++;
412 h.header_version_minor = htobe32(n32);
413 n32++;
414 h.authentication_data_block_size = htobe64(n64);
415 n64++;
416 h.auxiliary_data_block_size = htobe64(n64);
417 n64++;
418 h.algorithm_type = htobe32(n32);
419 n32++;
420 h.hash_offset = htobe64(n64);
421 n64++;
422 h.hash_size = htobe64(n64);
423 n64++;
424 h.signature_offset = htobe64(n64);
425 n64++;
426 h.signature_size = htobe64(n64);
427 n64++;
428 h.public_key_offset = htobe64(n64);
429 n64++;
430 h.public_key_size = htobe64(n64);
431 n64++;
432 h.descriptors_offset = htobe64(n64);
433 n64++;
434 h.descriptors_size = htobe64(n64);
435 n64++;
436 h.rollback_index = htobe64(n64);
437 n64++;
438
439 avb_vbmeta_image_header_to_host_byte_order(&h, &s);
440
441 n32 = 0x11223344;
442 n64 = 0x1122334455667788;
443
444 EXPECT_EQ(n32, s.header_version_major);
445 n32++;
446 EXPECT_EQ(n32, s.header_version_minor);
447 n32++;
448 EXPECT_EQ(n64, s.authentication_data_block_size);
449 n64++;
450 EXPECT_EQ(n64, s.auxiliary_data_block_size);
451 n64++;
452 EXPECT_EQ(n32, s.algorithm_type);
453 n32++;
454 EXPECT_EQ(n64, s.hash_offset);
455 n64++;
456 EXPECT_EQ(n64, s.hash_size);
457 n64++;
458 EXPECT_EQ(n64, s.signature_offset);
459 n64++;
460 EXPECT_EQ(n64, s.signature_size);
461 n64++;
462 EXPECT_EQ(n64, s.public_key_offset);
463 n64++;
464 EXPECT_EQ(n64, s.public_key_size);
465 n64++;
466 EXPECT_EQ(n64, s.descriptors_offset);
467 n64++;
468 EXPECT_EQ(n64, s.descriptors_size);
469 n64++;
470 EXPECT_EQ(n64, s.rollback_index);
471 n64++;
472
473 // If new fields are added, the following will fail. This is to
474 // remind that byteswapping code (in avb_util.c) and unittests for
475 // this should be updated.
476 static_assert(offsetof(AvbVBMetaImageHeader, reserved) == 104,
477 "Remember to unittest byteswapping of newly added fields");
478}