2 * Copyright (C) 2015 Google, Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <linux/buffer_head.h>
16 #include <linux/delay.h>
17 #include <linux/device.h>
18 #include <linux/device-mapper.h>
19 #include <linux/errno.h>
21 #include <linux/fcntl.h>
22 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/key.h>
25 #include <linux/module.h>
26 #include <linux/mount.h>
27 #include <linux/namei.h>
29 #include <linux/reboot.h>
30 #include <linux/string.h>
31 #include <linux/vmalloc.h>
33 #include <asm/setup.h>
34 #include <crypto/hash.h>
35 #include <crypto/public_key.h>
36 #include <crypto/sha.h>
37 #include <keys/asymmetric-type.h>
38 #include <keys/system_keyring.h>
40 #include "dm-verity.h"
41 #include "dm-android-verity.h"
43 static char verifiedbootstate[VERITY_COMMANDLINE_PARAM_LENGTH];
44 static char veritymode[VERITY_COMMANDLINE_PARAM_LENGTH];
46 static int __init verified_boot_state_param(char *line)
48 strlcpy(verifiedbootstate, line, sizeof(verifiedbootstate));
52 __setup("androidboot.verifiedbootstate=", verified_boot_state_param);
54 static int __init verity_mode_param(char *line)
56 strlcpy(veritymode, line, sizeof(veritymode));
60 __setup("androidboot.veritymode=", verity_mode_param);
62 static int table_extract_mpi_array(struct public_key_signature *pks,
63 const void *data, size_t len)
65 MPI mpi = mpi_read_raw_data(data, len);
68 DMERR("Error while allocating mpi array");
77 static struct public_key_signature *table_make_digest(
80 unsigned long table_len)
82 struct public_key_signature *pks = NULL;
83 struct crypto_shash *tfm;
84 struct shash_desc *desc;
85 size_t digest_size, desc_size;
88 /* Allocate the hashing algorithm we're going to need and find out how
89 * big the hash operational data will be.
91 tfm = crypto_alloc_shash(hash_algo_name[hash], 0, 0);
95 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
96 digest_size = crypto_shash_digestsize(tfm);
98 /* We allocate the hash operational data storage on the end of out
99 * context data and the digest output buffer on the end of that.
102 pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL);
106 pks->pkey_hash_algo = hash;
107 pks->digest = (u8 *)pks + sizeof(*pks) + desc_size;
108 pks->digest_size = digest_size;
110 desc = (struct shash_desc *)(pks + 1);
112 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
114 ret = crypto_shash_init(desc);
118 ret = crypto_shash_finup(desc, table, table_len, pks->digest);
122 crypto_free_shash(tfm);
127 crypto_free_shash(tfm);
131 static int read_block_dev(struct bio_read *payload, struct block_device *bdev,
132 sector_t offset, int length)
137 payload->number_of_pages = DIV_ROUND_UP(length, PAGE_SIZE);
139 bio = bio_alloc(GFP_KERNEL, payload->number_of_pages);
141 DMERR("Error while allocating bio");
146 bio->bi_iter.bi_sector = offset;
148 payload->page_io = kzalloc(sizeof(struct page *) *
149 payload->number_of_pages, GFP_KERNEL);
150 if (!payload->page_io) {
151 DMERR("page_io array alloc failed");
156 for (i = 0; i < payload->number_of_pages; i++) {
157 payload->page_io[i] = alloc_page(GFP_KERNEL);
158 if (!payload->page_io[i]) {
159 DMERR("alloc_page failed");
163 if (!bio_add_page(bio, payload->page_io[i], PAGE_SIZE, 0)) {
164 DMERR("bio_add_page error");
170 if (!submit_bio_wait(READ, bio))
173 DMERR("bio read failed");
177 for (i = 0; i < payload->number_of_pages; i++)
178 if (payload->page_io[i])
179 __free_page(payload->page_io[i]);
180 kfree(payload->page_io);
186 static inline u64 fec_div_round_up(u64 x, u64 y)
190 return div64_u64_rem(x, y, &remainder) +
191 (remainder > 0 ? 1 : 0);
194 static inline void populate_fec_metadata(struct fec_header *header,
195 struct fec_ecc_metadata *ecc)
197 ecc->blocks = fec_div_round_up(le64_to_cpu(header->inp_size),
199 ecc->roots = le32_to_cpu(header->roots);
200 ecc->start = le64_to_cpu(header->inp_size);
203 static inline int validate_fec_header(struct fec_header *header, u64 offset)
205 /* move offset to make the sanity check work for backup header
207 offset -= offset % FEC_BLOCK_SIZE;
208 if (le32_to_cpu(header->magic) != FEC_MAGIC ||
209 le32_to_cpu(header->version) != FEC_VERSION ||
210 le32_to_cpu(header->size) != sizeof(struct fec_header) ||
211 le32_to_cpu(header->roots) == 0 ||
212 le32_to_cpu(header->roots) >= FEC_RSM ||
213 offset < le32_to_cpu(header->fec_size) ||
214 offset - le32_to_cpu(header->fec_size) !=
215 le64_to_cpu(header->inp_size))
221 static int extract_fec_header(dev_t dev, struct fec_header *fec,
222 struct fec_ecc_metadata *ecc)
225 struct bio_read payload;
227 struct block_device *bdev;
229 bdev = blkdev_get_by_dev(dev, FMODE_READ, NULL);
232 DMERR("bdev get error");
233 return PTR_ERR(bdev);
236 device_size = i_size_read(bdev->bd_inode);
238 /* fec metadata size is a power of 2 and PAGE_SIZE
239 * is a power of 2 as well.
241 BUG_ON(FEC_BLOCK_SIZE > PAGE_SIZE);
242 /* 512 byte sector alignment */
243 BUG_ON(((device_size - FEC_BLOCK_SIZE) % (1 << SECTOR_SHIFT)) != 0);
245 err = read_block_dev(&payload, bdev, (device_size -
246 FEC_BLOCK_SIZE) / (1 << SECTOR_SHIFT), FEC_BLOCK_SIZE);
248 DMERR("Error while reading verity metadata");
252 BUG_ON(sizeof(struct fec_header) > PAGE_SIZE);
253 memcpy(fec, page_address(payload.page_io[0]),
257 if (validate_fec_header(fec, device_size - FEC_BLOCK_SIZE)) {
258 /* Try the backup header */
259 memcpy(fec, page_address(payload.page_io[0]) + FEC_BLOCK_SIZE
262 if (validate_fec_header(fec, device_size -
263 sizeof(struct fec_header)))
268 populate_fec_metadata(fec, ecc);
270 for (i = 0; i < payload.number_of_pages; i++)
271 __free_page(payload.page_io[i]);
272 kfree(payload.page_io);
275 blkdev_put(bdev, FMODE_READ);
278 static void find_metadata_offset(struct fec_header *fec,
279 struct block_device *bdev, u64 *metadata_offset)
283 device_size = i_size_read(bdev->bd_inode);
285 if (le32_to_cpu(fec->magic) == FEC_MAGIC)
286 *metadata_offset = le64_to_cpu(fec->inp_size) -
287 VERITY_METADATA_SIZE;
289 *metadata_offset = device_size - VERITY_METADATA_SIZE;
292 static struct android_metadata *extract_metadata(dev_t dev,
293 struct fec_header *fec)
295 struct block_device *bdev;
296 struct android_metadata_header *header;
297 struct android_metadata *uninitialized_var(metadata);
299 u32 table_length, copy_length, offset;
301 struct bio_read payload;
304 bdev = blkdev_get_by_dev(dev, FMODE_READ, NULL);
307 DMERR("blkdev_get_by_dev failed");
308 return ERR_CAST(bdev);
311 find_metadata_offset(fec, bdev, &metadata_offset);
313 /* Verity metadata size is a power of 2 and PAGE_SIZE
314 * is a power of 2 as well.
315 * PAGE_SIZE is also a multiple of 512 bytes.
317 if (VERITY_METADATA_SIZE > PAGE_SIZE)
318 BUG_ON(VERITY_METADATA_SIZE % PAGE_SIZE != 0);
319 /* 512 byte sector alignment */
320 BUG_ON(metadata_offset % (1 << SECTOR_SHIFT) != 0);
322 err = read_block_dev(&payload, bdev, metadata_offset /
323 (1 << SECTOR_SHIFT), VERITY_METADATA_SIZE);
325 DMERR("Error while reading verity metadata");
326 metadata = ERR_PTR(err);
330 header = kzalloc(sizeof(*header), GFP_KERNEL);
332 DMERR("kzalloc failed for header");
337 memcpy(header, page_address(payload.page_io[0]),
340 DMINFO("bio magic_number:%u protocol_version:%d table_length:%u",
341 le32_to_cpu(header->magic_number),
342 le32_to_cpu(header->protocol_version),
343 le32_to_cpu(header->table_length));
345 metadata = kzalloc(sizeof(*metadata), GFP_KERNEL);
347 DMERR("kzalloc for metadata failed");
352 metadata->header = header;
353 table_length = le32_to_cpu(header->table_length);
355 if (table_length == 0 ||
356 table_length > (VERITY_METADATA_SIZE -
357 sizeof(struct android_metadata_header)))
360 metadata->verity_table = kzalloc(table_length + 1, GFP_KERNEL);
362 if (!metadata->verity_table) {
363 DMERR("kzalloc verity_table failed");
368 if (sizeof(struct android_metadata_header) +
369 table_length <= PAGE_SIZE) {
370 memcpy(metadata->verity_table, page_address(payload.page_io[0])
371 + sizeof(struct android_metadata_header),
374 copy_length = PAGE_SIZE -
375 sizeof(struct android_metadata_header);
376 memcpy(metadata->verity_table, page_address(payload.page_io[0])
377 + sizeof(struct android_metadata_header),
379 table_length -= copy_length;
380 offset = copy_length;
382 while (table_length != 0) {
383 if (table_length > PAGE_SIZE) {
384 memcpy(metadata->verity_table + offset,
385 page_address(payload.page_io[i]),
388 table_length -= PAGE_SIZE;
390 memcpy(metadata->verity_table + offset,
391 page_address(payload.page_io[i]),
398 metadata->verity_table[table_length] = '\0';
406 metadata = ERR_PTR(err);
408 for (i = 0; i < payload.number_of_pages; i++)
409 if (payload.page_io[i])
410 __free_page(payload.page_io[i]);
411 kfree(payload.page_io);
413 DMINFO("verity_table: %s", metadata->verity_table);
415 blkdev_put(bdev, FMODE_READ);
419 /* helper functions to extract properties from dts */
420 const char *find_dt_value(const char *name)
422 struct device_node *firmware;
425 firmware = of_find_node_by_path("/firmware/android");
428 value = of_get_property(firmware, name, NULL);
429 of_node_put(firmware);
434 static bool is_unlocked(void)
436 static const char unlocked[] = "orange";
437 static const char verified_boot_prop[] = "verifiedbootstate";
440 value = find_dt_value(verified_boot_prop);
442 value = verifiedbootstate;
444 return !strncmp(value, unlocked, sizeof(unlocked) - 1);
447 static int verity_mode(void)
449 static const char enforcing[] = "enforcing";
450 static const char verified_mode_prop[] = "veritymode";
453 value = find_dt_value(verified_mode_prop);
456 if (!strncmp(value, enforcing, sizeof(enforcing) - 1))
457 return DM_VERITY_MODE_RESTART;
459 return DM_VERITY_MODE_EIO;
462 static int verify_header(struct android_metadata_header *header)
464 int retval = -EINVAL;
466 if (is_unlocked() && le32_to_cpu(header->magic_number) ==
467 VERITY_METADATA_MAGIC_DISABLE) {
468 retval = VERITY_STATE_DISABLE;
472 if (!(le32_to_cpu(header->magic_number) ==
473 VERITY_METADATA_MAGIC_NUMBER) ||
474 (le32_to_cpu(header->magic_number) ==
475 VERITY_METADATA_MAGIC_DISABLE)) {
476 DMERR("Incorrect magic number");
480 if (le32_to_cpu(header->protocol_version) !=
481 VERITY_METADATA_VERSION) {
482 DMERR("Unsupported version %u",
483 le32_to_cpu(header->protocol_version));
490 static int verify_verity_signature(char *key_id,
491 struct android_metadata *metadata)
495 struct public_key_signature *pks = NULL;
496 int retval = -EINVAL;
498 key_ref = keyring_search(make_key_ref(system_trusted_keyring, 1),
499 &key_type_asymmetric, key_id);
501 if (IS_ERR(key_ref)) {
502 DMERR("keyring: key not found");
506 key = key_ref_to_ptr(key_ref);
508 pks = table_make_digest(HASH_ALGO_SHA256,
509 (const void *)metadata->verity_table,
510 le32_to_cpu(metadata->header->table_length));
513 DMERR("hashing failed");
517 retval = table_extract_mpi_array(pks, &metadata->header->signature[0],
520 DMERR("Error extracting mpi %d", retval);
524 retval = verify_signature(key, pks);
525 mpi_free(pks->rsa.s);
533 static void handle_error(void)
535 int mode = verity_mode();
536 if (mode == DM_VERITY_MODE_RESTART) {
537 DMERR("triggering restart");
538 kernel_restart("dm-verity device corrupted");
540 DMERR("Mounting verity root failed");
544 static inline bool test_mult_overflow(sector_t a, u32 b)
546 sector_t r = (sector_t)~0ULL;
554 * <key id> Key id of the public key in the system keyring.
555 * Verity metadata's signature would be verified against
556 * this. If the key id contains spaces, replace them
558 * <block device> The block device for which dm-verity is being setup.
560 static int android_verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
562 dev_t uninitialized_var(dev);
563 struct android_metadata *uninitialized_var(metadata);
564 int err = 0, i, mode;
565 char *key_id, *table_ptr, dummy,
566 *verity_table_args[VERITY_TABLE_ARGS + 2 + VERITY_TABLE_OPT_FEC_ARGS];
567 /* One for specifying number of opt args and one for mode */
568 sector_t data_sectors;
570 unsigned int major, minor,
571 no_of_args = VERITY_TABLE_ARGS + 2 + VERITY_TABLE_OPT_FEC_ARGS;
572 struct fec_header uninitialized_var(fec);
573 struct fec_ecc_metadata uninitialized_var(ecc);
574 char buf[FEC_ARG_LENGTH], *buf_ptr;
575 unsigned long long tmpll;
578 DMERR("Incorrect number of arguments");
583 /* should come as one of the arguments for the verity target */
585 strreplace(argv[0], '#', ' ');
587 if (sscanf(argv[1], "%u:%u%c", &major, &minor, &dummy) == 2) {
588 dev = MKDEV(major, minor);
589 if (MAJOR(dev) != major || MINOR(dev) != minor) {
590 DMERR("Incorrect bdev major minor number");
596 DMINFO("key:%s dev:%s", argv[0], argv[1]);
598 if (extract_fec_header(dev, &fec, &ecc)) {
599 DMERR("Error while extracting fec header");
604 metadata = extract_metadata(dev, &fec);
606 if (IS_ERR(metadata)) {
607 DMERR("Error while extracting metadata");
612 err = verify_header(metadata->header);
614 if (err == VERITY_STATE_DISABLE) {
615 DMERR("Mounting root with verity disabled");
618 DMERR("Verity header handle error");
623 err = verify_verity_signature(key_id, metadata);
626 DMERR("Signature verification failed");
630 DMINFO("Signature verification success");
632 table_ptr = metadata->verity_table;
634 for (i = 0; i < VERITY_TABLE_ARGS; i++) {
635 verity_table_args[i] = strsep(&table_ptr, " ");
636 if (verity_table_args[i] == NULL)
640 if (i != VERITY_TABLE_ARGS) {
641 DMERR("Verity table not in the expected format");
647 if (sscanf(verity_table_args[5], "%llu%c", &tmpll, &dummy)
649 DMERR("Verity table not in the expected format");
655 if (tmpll > ULONG_MAX) {
656 DMERR("<num_data_blocks> too large. Forgot to turn on CONFIG_LBDAF?");
662 data_sectors = tmpll;
664 if (sscanf(verity_table_args[3], "%u%c", &data_block_size, &dummy)
666 DMERR("Verity table not in the expected format");
672 if (test_mult_overflow(data_sectors, data_block_size >>
674 DMERR("data_sectors too large");
680 data_sectors *= data_block_size >> SECTOR_SHIFT;
681 DMINFO("Data sectors %llu", (unsigned long long)data_sectors);
683 /* update target length */
684 ti->len = data_sectors;
686 /*substitute data_dev and hash_dev*/
687 verity_table_args[1] = argv[1];
688 verity_table_args[2] = argv[1];
690 mode = verity_mode();
692 if (ecc.valid && IS_BUILTIN(CONFIG_DM_VERITY_FEC)) {
694 err = snprintf(buf, FEC_ARG_LENGTH,
695 "%u %s " VERITY_TABLE_OPT_FEC_FORMAT,
696 1 + VERITY_TABLE_OPT_FEC_ARGS,
697 mode == DM_VERITY_MODE_RESTART ?
698 VERITY_TABLE_OPT_RESTART : VERITY_TABLE_OPT_LOGGING,
699 argv[1], ecc.start / FEC_BLOCK_SIZE, ecc.blocks,
702 err = snprintf(buf, FEC_ARG_LENGTH,
703 "%u " VERITY_TABLE_OPT_FEC_FORMAT,
704 VERITY_TABLE_OPT_FEC_ARGS, argv[1],
705 ecc.start / FEC_BLOCK_SIZE, ecc.blocks, ecc.roots);
708 err = snprintf(buf, FEC_ARG_LENGTH,
709 "2 " VERITY_TABLE_OPT_IGNZERO " %s",
710 mode == DM_VERITY_MODE_RESTART ?
711 VERITY_TABLE_OPT_RESTART : VERITY_TABLE_OPT_LOGGING);
713 err = snprintf(buf, FEC_ARG_LENGTH, "1 %s",
714 "ignore_zero_blocks");
717 if (err < 0 || err >= FEC_ARG_LENGTH)
722 for (i = VERITY_TABLE_ARGS; i < (VERITY_TABLE_ARGS +
723 VERITY_TABLE_OPT_FEC_ARGS + 2); i++) {
724 verity_table_args[i] = strsep(&buf_ptr, " ");
725 if (verity_table_args[i] == NULL) {
731 err = verity_ctr(ti, no_of_args, verity_table_args);
734 kfree(metadata->header);
735 kfree(metadata->verity_table);
740 static struct target_type android_verity_target = {
741 .name = "android-verity",
742 .version = {1, 0, 0},
743 .module = THIS_MODULE,
744 .ctr = android_verity_ctr,
747 .status = verity_status,
748 .ioctl = verity_ioctl,
749 .merge = verity_merge,
750 .iterate_devices = verity_iterate_devices,
751 .io_hints = verity_io_hints,
754 static int __init dm_android_verity_init(void)
758 r = dm_register_target(&android_verity_target);
760 DMERR("register failed %d", r);
765 static void __exit dm_android_verity_exit(void)
767 dm_unregister_target(&android_verity_target);
770 module_init(dm_android_verity_init);
771 module_exit(dm_android_verity_exit);