2 * (C) Copyright 2018, Linaro Limited
4 * SPDX-License-Identifier: GPL-2.0+
7 #include <avb_verify.h>
13 const unsigned char avb_root_pub[1032] = {
14 0x0, 0x0, 0x10, 0x0, 0x55, 0xd9, 0x4, 0xad, 0xd8, 0x4,
15 0xaf, 0xe3, 0xd3, 0x84, 0x6c, 0x7e, 0xd, 0x89, 0x3d, 0xc2,
16 0x8c, 0xd3, 0x12, 0x55, 0xe9, 0x62, 0xc9, 0xf1, 0xf, 0x5e,
17 0xcc, 0x16, 0x72, 0xab, 0x44, 0x7c, 0x2c, 0x65, 0x4a, 0x94,
18 0xb5, 0x16, 0x2b, 0x0, 0xbb, 0x6, 0xef, 0x13, 0x7, 0x53,
19 0x4c, 0xf9, 0x64, 0xb9, 0x28, 0x7a, 0x1b, 0x84, 0x98, 0x88,
20 0xd8, 0x67, 0xa4, 0x23, 0xf9, 0xa7, 0x4b, 0xdc, 0x4a, 0xf,
21 0xf7, 0x3a, 0x18, 0xae, 0x54, 0xa8, 0x15, 0xfe, 0xb0, 0xad,
22 0xac, 0x35, 0xda, 0x3b, 0xad, 0x27, 0xbc, 0xaf, 0xe8, 0xd3,
23 0x2f, 0x37, 0x34, 0xd6, 0x51, 0x2b, 0x6c, 0x5a, 0x27, 0xd7,
24 0x96, 0x6, 0xaf, 0x6b, 0xb8, 0x80, 0xca, 0xfa, 0x30, 0xb4,
25 0xb1, 0x85, 0xb3, 0x4d, 0xaa, 0xaa, 0xc3, 0x16, 0x34, 0x1a,
26 0xb8, 0xe7, 0xc7, 0xfa, 0xf9, 0x9, 0x77, 0xab, 0x97, 0x93,
27 0xeb, 0x44, 0xae, 0xcf, 0x20, 0xbc, 0xf0, 0x80, 0x11, 0xdb,
28 0x23, 0xc, 0x47, 0x71, 0xb9, 0x6d, 0xd6, 0x7b, 0x60, 0x47,
29 0x87, 0x16, 0x56, 0x93, 0xb7, 0xc2, 0x2a, 0x9a, 0xb0, 0x4c,
30 0x1, 0xc, 0x30, 0xd8, 0x93, 0x87, 0xf0, 0xed, 0x6e, 0x8b,
31 0xbe, 0x30, 0x5b, 0xf6, 0xa6, 0xaf, 0xdd, 0x80, 0x7c, 0x45,
32 0x5e, 0x8f, 0x91, 0x93, 0x5e, 0x44, 0xfe, 0xb8, 0x82, 0x7,
33 0xee, 0x79, 0xca, 0xbf, 0x31, 0x73, 0x62, 0x58, 0xe3, 0xcd,
34 0xc4, 0xbc, 0xc2, 0x11, 0x1d, 0xa1, 0x4a, 0xbf, 0xfe, 0x27,
35 0x7d, 0xa1, 0xf6, 0x35, 0xa3, 0x5e, 0xca, 0xdc, 0x57, 0x2f,
36 0x3e, 0xf0, 0xc9, 0x5d, 0x86, 0x6a, 0xf8, 0xaf, 0x66, 0xa7,
37 0xed, 0xcd, 0xb8, 0xed, 0xa1, 0x5f, 0xba, 0x9b, 0x85, 0x1a,
38 0xd5, 0x9, 0xae, 0x94, 0x4e, 0x3b, 0xcf, 0xcb, 0x5c, 0xc9,
39 0x79, 0x80, 0xf7, 0xcc, 0xa6, 0x4a, 0xa8, 0x6a, 0xd8, 0xd3,
40 0x31, 0x11, 0xf9, 0xf6, 0x2, 0x63, 0x2a, 0x1a, 0x2d, 0xd1,
41 0x1a, 0x66, 0x1b, 0x16, 0x41, 0xbd, 0xbd, 0xf7, 0x4d, 0xc0,
42 0x4a, 0xe5, 0x27, 0x49, 0x5f, 0x7f, 0x58, 0xe3, 0x27, 0x2d,
43 0xe5, 0xc9, 0x66, 0xe, 0x52, 0x38, 0x16, 0x38, 0xfb, 0x16,
44 0xeb, 0x53, 0x3f, 0xe6, 0xfd, 0xe9, 0xa2, 0x5e, 0x25, 0x59,
45 0xd8, 0x79, 0x45, 0xff, 0x3, 0x4c, 0x26, 0xa2, 0x0, 0x5a,
46 0x8e, 0xc2, 0x51, 0xa1, 0x15, 0xf9, 0x7b, 0xf4, 0x5c, 0x81,
47 0x9b, 0x18, 0x47, 0x35, 0xd8, 0x2d, 0x5, 0xe9, 0xad, 0xf,
48 0x35, 0x74, 0x15, 0xa3, 0x8e, 0x8b, 0xcc, 0x27, 0xda, 0x7c,
49 0x5d, 0xe4, 0xfa, 0x4, 0xd3, 0x5, 0xb, 0xba, 0x3a, 0xb2,
50 0x49, 0x45, 0x2f, 0x47, 0xc7, 0xd, 0x41, 0x3f, 0x97, 0x80,
51 0x4d, 0x3f, 0xc1, 0xb5, 0xbb, 0x70, 0x5f, 0xa7, 0x37, 0xaf,
52 0x48, 0x22, 0x12, 0x45, 0x2e, 0xf5, 0xf, 0x87, 0x92, 0xe2,
53 0x84, 0x1, 0xf9, 0x12, 0xf, 0x14, 0x15, 0x24, 0xce, 0x89,
54 0x99, 0xee, 0xb9, 0xc4, 0x17, 0x70, 0x70, 0x15, 0xea, 0xbe,
55 0xc6, 0x6c, 0x1f, 0x62, 0xb3, 0xf4, 0x2d, 0x16, 0x87, 0xfb,
56 0x56, 0x1e, 0x45, 0xab, 0xae, 0x32, 0xe4, 0x5e, 0x91, 0xed,
57 0x53, 0x66, 0x5e, 0xbd, 0xed, 0xad, 0xe6, 0x12, 0x39, 0xd,
58 0x83, 0xc9, 0xe8, 0x6b, 0x6c, 0x2d, 0xa5, 0xee, 0xc4, 0x5a,
59 0x66, 0xae, 0x8c, 0x97, 0xd7, 0xd, 0x6c, 0x49, 0xc7, 0xf5,
60 0xc4, 0x92, 0x31, 0x8b, 0x9, 0xee, 0x33, 0xda, 0xa9, 0x37,
61 0xb6, 0x49, 0x18, 0xf8, 0xe, 0x60, 0x45, 0xc8, 0x33, 0x91,
62 0xef, 0x20, 0x57, 0x10, 0xbe, 0x78, 0x2d, 0x83, 0x26, 0xd6,
63 0xca, 0x61, 0xf9, 0x2f, 0xe0, 0xbf, 0x5, 0x30, 0x52, 0x5a,
64 0x12, 0x1c, 0x0, 0xa7, 0x5d, 0xcc, 0x7c, 0x2e, 0xc5, 0x95,
65 0x8b, 0xa3, 0x3b, 0xf0, 0x43, 0x2e, 0x5e, 0xdd, 0x0, 0xdb,
66 0xd, 0xb3, 0x37, 0x99, 0xa9, 0xcd, 0x9c, 0xb7, 0x43, 0xf7,
67 0x35, 0x44, 0x21, 0xc2, 0x82, 0x71, 0xab, 0x8d, 0xaa, 0xb4,
68 0x41, 0x11, 0xec, 0x1e, 0x8d, 0xfc, 0x14, 0x82, 0x92, 0x4e,
69 0x83, 0x6a, 0xa, 0x6b, 0x35, 0x5e, 0x5d, 0xe9, 0x5c, 0xcc,
70 0x8c, 0xde, 0x39, 0xd1, 0x4a, 0x5b, 0x5f, 0x63, 0xa9, 0x64,
71 0xe0, 0xa, 0xcb, 0xb, 0xb8, 0x5a, 0x7c, 0xc3, 0xb, 0xe6,
72 0xbe, 0xfe, 0x8b, 0xf, 0x7d, 0x34, 0x8e, 0x2, 0x66, 0x74,
73 0x1, 0x6c, 0xca, 0x76, 0xac, 0x7c, 0x67, 0x8, 0x2f, 0x3f,
74 0x1a, 0xa6, 0x2c, 0x60, 0xb3, 0xff, 0xda, 0x8d, 0xb8, 0x12,
75 0xc, 0x0, 0x7f, 0xcc, 0x50, 0xa1, 0x5c, 0x64, 0xa1, 0xe2,
76 0x5f, 0x32, 0x65, 0xc9, 0x9c, 0xbe, 0xd6, 0xa, 0x13, 0x87,
77 0x3c, 0x2a, 0x45, 0x47, 0xc, 0xca, 0x42, 0x82, 0xfa, 0x89,
78 0x65, 0xe7, 0x89, 0xb4, 0x8f, 0xf7, 0x1e, 0xe6, 0x23, 0xa5,
79 0xd0, 0x59, 0x37, 0x79, 0x92, 0xd7, 0xce, 0x3d, 0xfd, 0xe3,
80 0xa1, 0xb, 0xcf, 0x6c, 0x85, 0xa0, 0x65, 0xf3, 0x5c, 0xc6,
81 0x4a, 0x63, 0x5f, 0x6e, 0x3a, 0x3a, 0x2a, 0x8b, 0x6a, 0xb6,
82 0x2f, 0xbb, 0xf8, 0xb2, 0x4b, 0x62, 0xbc, 0x1a, 0x91, 0x25,
83 0x66, 0xe3, 0x69, 0xca, 0x60, 0x49, 0xb, 0xf6, 0x8a, 0xbe,
84 0x3e, 0x76, 0x53, 0xc2, 0x7a, 0xa8, 0x4, 0x17, 0x75, 0xf1,
85 0xf3, 0x3, 0x62, 0x1b, 0x85, 0xb2, 0xb0, 0xef, 0x80, 0x15,
86 0xb6, 0xd4, 0x4e, 0xdf, 0x71, 0xac, 0xdb, 0x2a, 0x4, 0xd4,
87 0xb4, 0x21, 0xba, 0x65, 0x56, 0x57, 0xe8, 0xfa, 0x84, 0xa2,
88 0x7d, 0x13, 0xe, 0xaf, 0xd7, 0x9a, 0x58, 0x2a, 0xa3, 0x81,
89 0x84, 0x8d, 0x9, 0xa0, 0x6a, 0xc1, 0xbb, 0xd9, 0xf5, 0x86,
90 0xac, 0xbd, 0x75, 0x61, 0x9, 0xe6, 0x8c, 0x3d, 0x77, 0xb2,
91 0xed, 0x30, 0x20, 0xe4, 0x0, 0x1d, 0x97, 0xe8, 0xbf, 0xc7,
92 0x0, 0x1b, 0x21, 0xb1, 0x16, 0xe7, 0x41, 0x67, 0x2e, 0xec,
93 0x38, 0xbc, 0xe5, 0x1b, 0xb4, 0x6, 0x23, 0x31, 0x71, 0x1c,
94 0x49, 0xcd, 0x76, 0x4a, 0x76, 0x36, 0x8d, 0xa3, 0x89, 0x8b,
95 0x4a, 0x7a, 0xf4, 0x87, 0xc8, 0x15, 0xf, 0x37, 0x39, 0xf6,
96 0x6d, 0x80, 0x19, 0xef, 0x5c, 0xa8, 0x66, 0xce, 0x1b, 0x16,
97 0x79, 0x21, 0xdf, 0xd7, 0x31, 0x30, 0xc4, 0x21, 0xdd, 0x34,
98 0x5b, 0xd2, 0x1a, 0x2b, 0x3e, 0x5d, 0xf7, 0xea, 0xca, 0x5,
99 0x8e, 0xb7, 0xcb, 0x49, 0x2e, 0xa0, 0xe3, 0xf4, 0xa7, 0x48,
100 0x19, 0x10, 0x9c, 0x4, 0xa7, 0xf4, 0x28, 0x74, 0xc8, 0x6f,
101 0x63, 0x20, 0x2b, 0x46, 0x24, 0x26, 0x19, 0x1d, 0xd1, 0x2c,
102 0x31, 0x6d, 0x5a, 0x29, 0xa2, 0x6, 0xa6, 0xb2, 0x41, 0xcc,
103 0xa, 0x27, 0x96, 0x9, 0x96, 0xac, 0x47, 0x65, 0x78, 0x68,
104 0x51, 0x98, 0xd6, 0xd8, 0xa6, 0x2d, 0xa0, 0xcf, 0xec, 0xe2,
105 0x74, 0xf2, 0x82, 0xe3, 0x97, 0xd9, 0x7e, 0xd4, 0xf8, 0xb,
106 0x70, 0x43, 0x3d, 0xb1, 0x7b, 0x97, 0x80, 0xd6, 0xcb, 0xd7,
107 0x19, 0xbc, 0x63, 0xb, 0xfd, 0x4d, 0x88, 0xfe, 0x67, 0xac,
108 0xb8, 0xcc, 0x50, 0xb7, 0x68, 0xb3, 0x5b, 0xd6, 0x1e, 0x25,
109 0xfc, 0x5f, 0x3c, 0x8d, 0xb1, 0x33, 0x7c, 0xb3, 0x49, 0x1,
110 0x3f, 0x71, 0x55, 0xe, 0x51, 0xba, 0x61, 0x26, 0xfa, 0xea,
111 0xe5, 0xb5, 0xe8, 0xaa, 0xcf, 0xcd, 0x96, 0x9f, 0xd6, 0xc1,
112 0x5f, 0x53, 0x91, 0xad, 0x5, 0xde, 0x20, 0xe7, 0x51, 0xda,
113 0x5b, 0x95, 0x67, 0xed, 0xf4, 0xee, 0x42, 0x65, 0x70, 0x13,
114 0xb, 0x70, 0x14, 0x1c, 0xc9, 0xe0, 0x19, 0xca, 0x5f, 0xf5,
115 0x1d, 0x70, 0x4b, 0x6c, 0x6, 0x74, 0xec, 0xb5, 0x2e, 0x77,
116 0xe1, 0x74, 0xa1, 0xa3, 0x99, 0xa0, 0x85, 0x9e, 0xf1, 0xac,
121 * ============================================================================
122 * Boot states support (GREEN, YELLOW, ORANGE, RED) and dm_verity
123 * ============================================================================
125 char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state)
127 struct AvbOpsData *data;
128 char *cmdline = NULL;
133 data = (struct AvbOpsData *)ops->user_data;
137 data->boot_state = boot_state;
138 switch (boot_state) {
140 cmdline = "androidboot.verifiedbootstate=green";
143 cmdline = "androidboot.verifiedbootstate=yellow";
146 cmdline = "androidboot.verifiedbootstate=orange";
154 char *append_cmd_line(char *cmdline_orig, char *cmdline_new)
162 cmd_line = cmdline_orig;
166 cmd_line = avb_strdupv(cmd_line, " ", cmdline_new, NULL);
171 static int avb_find_dm_args(char **args, char *str)
178 for (i = 0; i < AVB_MAX_ARGS, args[i]; ++i) {
179 if (strstr(args[i], str))
186 static char *avb_set_enforce_option(const char *cmdline, const char *option)
188 char *cmdarg[AVB_MAX_ARGS];
189 char *newargs = NULL;
193 memset(cmdarg, 0, sizeof(cmdarg));
194 cmdarg[i++] = strtok((char *)cmdline, " ");
197 cmdarg[i] = strtok(NULL, " ");
201 if (++i >= AVB_MAX_ARGS) {
202 printf("%s: Can't handle more then %d args\n",
209 i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_LOGGING);
211 cmdarg[i] = (char *)option;
213 i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_RESTART);
215 printf("%s: No verity options found\n", __func__);
219 cmdarg[i] = (char *)option;
222 for (i = 0; i <= total_args; i++)
223 newargs = append_cmd_line(newargs, cmdarg[i]);
228 char *avb_set_ignore_corruption(const char *cmdline)
230 char *newargs = NULL;
232 newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_LOGGING);
234 newargs = append_cmd_line(newargs,
235 "androidboot.veritymode=eio");
240 char *avb_set_enforce_verity(const char *cmdline)
244 newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_RESTART);
246 newargs = append_cmd_line(newargs,
247 "androidboot.veritymode=enforcing");
252 * ============================================================================
253 * IO(mmc) auxiliary functions
254 * ============================================================================
256 static unsigned long mmc_read_and_flush(struct mmc_part *part,
264 bool unaligned = is_buf_unaligned(buffer);
266 if (start < part->info.start) {
267 printf("%s: partition start out of bounds\n", __func__);
270 if ((start + sectors) > (part->info.start + part->info.size)) {
271 sectors = part->info.start + part->info.size - start;
272 printf("%s: read sector aligned to partition bounds (%ld)\n",
277 * Reading fails on unaligned buffers, so we have to
278 * use aligned temporary buffer and then copy to destination
282 printf("Handling unaligned read buffer..\n");
283 tmp_buf = get_sector_buf();
284 buf_size = get_sector_buf_size();
285 if (sectors > buf_size / part->info.blksz)
286 sectors = buf_size / part->info.blksz;
291 blks = part->mmc->block_dev.block_read(part->mmc_blk,
292 start, sectors, tmp_buf);
293 /* flush cache after read */
294 flush_cache((ulong)tmp_buf, sectors * part->info.blksz);
297 memcpy(buffer, tmp_buf, sectors * part->info.blksz);
302 static unsigned long mmc_write(struct mmc_part *part, lbaint_t start,
303 lbaint_t sectors, void *buffer)
307 bool unaligned = is_buf_unaligned(buffer);
309 if (start < part->info.start) {
310 printf("%s: partition start out of bounds\n", __func__);
313 if ((start + sectors) > (part->info.start + part->info.size)) {
314 sectors = part->info.start + part->info.size - start;
315 printf("%s: sector aligned to partition bounds (%ld)\n",
319 tmp_buf = get_sector_buf();
320 buf_size = get_sector_buf_size();
321 printf("Handling unaligned wrire buffer..\n");
322 if (sectors > buf_size / part->info.blksz)
323 sectors = buf_size / part->info.blksz;
325 memcpy(tmp_buf, buffer, sectors * part->info.blksz);
330 return part->mmc->block_dev.block_write(part->mmc_blk,
331 start, sectors, tmp_buf);
334 static struct mmc_part *get_partition(AvbOps *ops, const char *partition)
339 struct mmc_part *part;
340 struct blk_desc *mmc_blk;
342 part = malloc(sizeof(struct mmc_part));
346 dev_num = get_boot_device(ops);
347 part->mmc = find_mmc_device(dev_num);
349 printf("No MMC device at slot %x\n", dev_num);
353 if (mmc_init(part->mmc)) {
354 printf("MMC initialization failed\n");
358 ret = mmc_switch_part(part->mmc, part_num);
362 mmc_blk = mmc_get_blk_desc(part->mmc);
364 printf("Error - failed to obtain block descriptor\n");
368 ret = part_get_info_by_name(mmc_blk, partition, &part->info);
370 printf("Can't find partition '%s'\n", partition);
374 part->dev_num = dev_num;
375 part->mmc_blk = mmc_blk;
380 static AvbIOResult mmc_byte_io(AvbOps *ops,
381 const char *partition,
385 size_t *out_num_read,
386 enum mmc_io_type io_type)
389 struct mmc_part *part;
390 u64 start_offset, start_sector, sectors, residue;
394 if (!partition || !buffer || io_type > IO_WRITE)
395 return AVB_IO_RESULT_ERROR_IO;
397 part = get_partition(ops, partition);
399 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
401 start_offset = calc_offset(part, offset);
403 start_sector = start_offset / part->info.blksz;
404 sectors = num_bytes / part->info.blksz;
405 /* handle non block-aligned reads */
406 if (start_offset % part->info.blksz ||
407 num_bytes < part->info.blksz) {
408 tmp_buf = get_sector_buf();
409 if (start_offset % part->info.blksz) {
410 residue = part->info.blksz -
411 (start_offset % part->info.blksz);
412 if (residue > num_bytes)
418 if (io_type == IO_READ) {
419 ret = mmc_read_and_flush(part,
425 printf("%s: read error (%ld, %lld)\n",
426 __func__, ret, start_sector);
427 return AVB_IO_RESULT_ERROR_IO;
430 * if this is not aligned at sector start,
431 * we have to adjust the tmp buffer
433 tmp_buf += (start_offset % part->info.blksz);
434 memcpy(buffer, (void *)tmp_buf, residue);
436 ret = mmc_read_and_flush(part,
442 printf("%s: read error (%ld, %lld)\n",
443 __func__, ret, start_sector);
444 return AVB_IO_RESULT_ERROR_IO;
446 memcpy((void *)tmp_buf +
447 start_offset % part->info.blksz,
450 ret = mmc_write(part, part->info.start +
451 start_sector, 1, tmp_buf);
453 printf("%s: write error (%ld, %lld)\n",
454 __func__, ret, start_sector);
455 return AVB_IO_RESULT_ERROR_IO;
461 start_offset += residue;
462 num_bytes -= residue;
467 if (io_type == IO_READ) {
468 ret = mmc_read_and_flush(part,
473 ret = mmc_write(part,
480 printf("%s: sector read error\n", __func__);
481 return AVB_IO_RESULT_ERROR_IO;
484 io_cnt += ret * part->info.blksz;
485 buffer += ret * part->info.blksz;
486 start_offset += ret * part->info.blksz;
487 num_bytes -= ret * part->info.blksz;
491 /* Set counter for read operation */
492 if (io_type == IO_READ && out_num_read)
493 *out_num_read = io_cnt;
495 return AVB_IO_RESULT_OK;
499 * ============================================================================
501 * ============================================================================
505 * read_from_partition() - reads @num_bytes from @offset from partition
506 * identified by a string name
508 * @ops: contains AVB ops handlers
509 * @partition_name: partition name, NUL-terminated UTF-8 string
510 * @offset: offset from the beginning of partition
511 * @num_bytes: amount of bytes to read
512 * @buffer: destination buffer to store data
516 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
517 * AVB_IO_RESULT_ERROR_IO, if i/o error occurred from the underlying i/o
519 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if there is no partition with
522 static AvbIOResult read_from_partition(AvbOps *ops,
523 const char *partition_name,
524 s64 offset_from_partition,
527 size_t *out_num_read)
529 return mmc_byte_io(ops, partition_name, offset_from_partition,
530 num_bytes, buffer, out_num_read, IO_READ);
534 * write_to_partition() - writes N bytes to a partition identified by a string
537 * @ops: AvbOps, contains AVB ops handlers
538 * @partition_name: partition name
539 * @offset_from_partition: offset from the beginning of partition
540 * @num_bytes: amount of bytes to write
541 * @buf: data to write
545 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
546 * AVB_IO_RESULT_ERROR_IO, if input/output error occurred
547 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition, specified in
548 * @partition_name was not found
550 static AvbIOResult write_to_partition(AvbOps *ops,
551 const char *partition_name,
552 s64 offset_from_partition,
556 return mmc_byte_io(ops, partition_name, offset_from_partition,
557 num_bytes, (void *)buffer, NULL, IO_WRITE);
561 * validate_vmbeta_public_key() - checks if the given public key used to sign
562 * the vbmeta partition is trusted
564 * @ops: AvbOps, contains AVB ops handlers
565 * @public_key_data: public key for verifying vbmeta partition signature
566 * @public_key_length: length of public key
567 * @public_key_metadata:
568 * @public_key_metadata_length:
569 * @out_key_is_trusted:
572 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
574 static AvbIOResult validate_vbmeta_public_key(AvbOps *ops,
575 const u8 *public_key_data,
576 size_t public_key_length,
578 *public_key_metadata,
580 public_key_metadata_length,
581 bool *out_key_is_trusted)
583 if (!public_key_length || !public_key_data || !out_key_is_trusted)
584 return AVB_IO_RESULT_ERROR_IO;
586 *out_key_is_trusted = false;
587 if (public_key_length != sizeof(avb_root_pub))
588 return AVB_IO_RESULT_ERROR_IO;
590 if (memcmp(avb_root_pub, public_key_data, public_key_length) == 0)
591 *out_key_is_trusted = true;
593 return AVB_IO_RESULT_OK;
597 * read_rollback_index() - gets the rollback index corresponding to the
598 * location of given by @out_rollback_index.
600 * @ops: contains AvbOps handlers
601 * @rollback_index_slot:
602 * @out_rollback_index: used to write a retrieved rollback index.
605 * AVB_IO_RESULT_OK, if the roolback index was retrieved
607 static AvbIOResult read_rollback_index(AvbOps *ops,
608 size_t rollback_index_slot,
609 u64 *out_rollback_index)
611 /* For now we always return 0 as the stored rollback index. */
612 printf("%s not supported yet\n", __func__);
614 if (out_rollback_index)
615 *out_rollback_index = 0;
617 return AVB_IO_RESULT_OK;
621 * write_rollback_index() - sets the rollback index corresponding to the
622 * location of given by @out_rollback_index.
624 * @ops: contains AvbOps handlers
625 * @rollback_index_slot:
626 * @rollback_index: rollback index to write.
629 * AVB_IO_RESULT_OK, if the roolback index was retrieved
631 static AvbIOResult write_rollback_index(AvbOps *ops,
632 size_t rollback_index_slot,
635 /* For now this is a no-op. */
636 printf("%s not supported yet\n", __func__);
638 return AVB_IO_RESULT_OK;
642 * read_is_device_unlocked() - gets whether the device is unlocked
644 * @ops: contains AVB ops handlers
645 * @out_is_unlocked: device unlock state is stored here, true if unlocked,
649 * AVB_IO_RESULT_OK: state is retrieved successfully
650 * AVB_IO_RESULT_ERROR_IO: an error occurred
652 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
654 /* For now we always return that the device is unlocked. */
656 printf("%s not supported yet\n", __func__);
658 *out_is_unlocked = true;
660 return AVB_IO_RESULT_OK;
664 * get_unique_guid_for_partition() - gets the GUID for a partition identified
667 * @ops: contains AVB ops handlers
668 * @partition: partition name (NUL-terminated UTF-8 string)
669 * @guid_buf: buf, used to copy in GUID string. Example of value:
670 * 527c1c6d-6361-4593-8842-3c78fcd39219
671 * @guid_buf_size: @guid_buf buffer size
674 * AVB_IO_RESULT_OK, on success (GUID found)
675 * AVB_IO_RESULT_ERROR_IO, if incorrect buffer size (@guid_buf_size) was
677 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found
679 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
680 const char *partition,
682 size_t guid_buf_size)
684 struct mmc_part *part;
687 part = get_partition(ops, partition);
689 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
691 uuid_size = sizeof(part->info.uuid);
692 if (uuid_size > guid_buf_size)
693 return AVB_IO_RESULT_ERROR_IO;
695 memcpy(guid_buf, part->info.uuid, uuid_size);
696 guid_buf[uuid_size - 1] = 0;
698 return AVB_IO_RESULT_OK;
702 * ============================================================================
703 * AVB2.0 AvbOps alloc/initialisation/free
704 * ============================================================================
706 AvbOps *avb_ops_alloc(int boot_device)
708 struct AvbOpsData *ops_data;
710 ops_data = avb_calloc(sizeof(struct AvbOpsData));
714 ops_data->ops.user_data = ops_data;
716 ops_data->ops.read_from_partition = read_from_partition;
717 ops_data->ops.write_to_partition = write_to_partition;
718 ops_data->ops.validate_vbmeta_public_key = validate_vbmeta_public_key;
719 ops_data->ops.read_rollback_index = read_rollback_index;
720 ops_data->ops.write_rollback_index = write_rollback_index;
721 ops_data->ops.read_is_device_unlocked = read_is_device_unlocked;
722 ops_data->ops.get_unique_guid_for_partition =
723 get_unique_guid_for_partition;
725 ops_data->mmc_dev = boot_device;
727 return &ops_data->ops;
730 void avb_ops_free(AvbOps *ops)
732 struct AvbOpsData *ops_data;
737 ops_data = ops->user_data;