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