2 * (C) Copyright 2018, Linaro Limited
4 * SPDX-License-Identifier: GPL-2.0+
7 #include <avb_verify.h>
14 static const unsigned char avb_root_pub[1032] = {
15 0x0, 0x0, 0x10, 0x0, 0x55, 0xd9, 0x4, 0xad, 0xd8, 0x4,
16 0xaf, 0xe3, 0xd3, 0x84, 0x6c, 0x7e, 0xd, 0x89, 0x3d, 0xc2,
17 0x8c, 0xd3, 0x12, 0x55, 0xe9, 0x62, 0xc9, 0xf1, 0xf, 0x5e,
18 0xcc, 0x16, 0x72, 0xab, 0x44, 0x7c, 0x2c, 0x65, 0x4a, 0x94,
19 0xb5, 0x16, 0x2b, 0x0, 0xbb, 0x6, 0xef, 0x13, 0x7, 0x53,
20 0x4c, 0xf9, 0x64, 0xb9, 0x28, 0x7a, 0x1b, 0x84, 0x98, 0x88,
21 0xd8, 0x67, 0xa4, 0x23, 0xf9, 0xa7, 0x4b, 0xdc, 0x4a, 0xf,
22 0xf7, 0x3a, 0x18, 0xae, 0x54, 0xa8, 0x15, 0xfe, 0xb0, 0xad,
23 0xac, 0x35, 0xda, 0x3b, 0xad, 0x27, 0xbc, 0xaf, 0xe8, 0xd3,
24 0x2f, 0x37, 0x34, 0xd6, 0x51, 0x2b, 0x6c, 0x5a, 0x27, 0xd7,
25 0x96, 0x6, 0xaf, 0x6b, 0xb8, 0x80, 0xca, 0xfa, 0x30, 0xb4,
26 0xb1, 0x85, 0xb3, 0x4d, 0xaa, 0xaa, 0xc3, 0x16, 0x34, 0x1a,
27 0xb8, 0xe7, 0xc7, 0xfa, 0xf9, 0x9, 0x77, 0xab, 0x97, 0x93,
28 0xeb, 0x44, 0xae, 0xcf, 0x20, 0xbc, 0xf0, 0x80, 0x11, 0xdb,
29 0x23, 0xc, 0x47, 0x71, 0xb9, 0x6d, 0xd6, 0x7b, 0x60, 0x47,
30 0x87, 0x16, 0x56, 0x93, 0xb7, 0xc2, 0x2a, 0x9a, 0xb0, 0x4c,
31 0x1, 0xc, 0x30, 0xd8, 0x93, 0x87, 0xf0, 0xed, 0x6e, 0x8b,
32 0xbe, 0x30, 0x5b, 0xf6, 0xa6, 0xaf, 0xdd, 0x80, 0x7c, 0x45,
33 0x5e, 0x8f, 0x91, 0x93, 0x5e, 0x44, 0xfe, 0xb8, 0x82, 0x7,
34 0xee, 0x79, 0xca, 0xbf, 0x31, 0x73, 0x62, 0x58, 0xe3, 0xcd,
35 0xc4, 0xbc, 0xc2, 0x11, 0x1d, 0xa1, 0x4a, 0xbf, 0xfe, 0x27,
36 0x7d, 0xa1, 0xf6, 0x35, 0xa3, 0x5e, 0xca, 0xdc, 0x57, 0x2f,
37 0x3e, 0xf0, 0xc9, 0x5d, 0x86, 0x6a, 0xf8, 0xaf, 0x66, 0xa7,
38 0xed, 0xcd, 0xb8, 0xed, 0xa1, 0x5f, 0xba, 0x9b, 0x85, 0x1a,
39 0xd5, 0x9, 0xae, 0x94, 0x4e, 0x3b, 0xcf, 0xcb, 0x5c, 0xc9,
40 0x79, 0x80, 0xf7, 0xcc, 0xa6, 0x4a, 0xa8, 0x6a, 0xd8, 0xd3,
41 0x31, 0x11, 0xf9, 0xf6, 0x2, 0x63, 0x2a, 0x1a, 0x2d, 0xd1,
42 0x1a, 0x66, 0x1b, 0x16, 0x41, 0xbd, 0xbd, 0xf7, 0x4d, 0xc0,
43 0x4a, 0xe5, 0x27, 0x49, 0x5f, 0x7f, 0x58, 0xe3, 0x27, 0x2d,
44 0xe5, 0xc9, 0x66, 0xe, 0x52, 0x38, 0x16, 0x38, 0xfb, 0x16,
45 0xeb, 0x53, 0x3f, 0xe6, 0xfd, 0xe9, 0xa2, 0x5e, 0x25, 0x59,
46 0xd8, 0x79, 0x45, 0xff, 0x3, 0x4c, 0x26, 0xa2, 0x0, 0x5a,
47 0x8e, 0xc2, 0x51, 0xa1, 0x15, 0xf9, 0x7b, 0xf4, 0x5c, 0x81,
48 0x9b, 0x18, 0x47, 0x35, 0xd8, 0x2d, 0x5, 0xe9, 0xad, 0xf,
49 0x35, 0x74, 0x15, 0xa3, 0x8e, 0x8b, 0xcc, 0x27, 0xda, 0x7c,
50 0x5d, 0xe4, 0xfa, 0x4, 0xd3, 0x5, 0xb, 0xba, 0x3a, 0xb2,
51 0x49, 0x45, 0x2f, 0x47, 0xc7, 0xd, 0x41, 0x3f, 0x97, 0x80,
52 0x4d, 0x3f, 0xc1, 0xb5, 0xbb, 0x70, 0x5f, 0xa7, 0x37, 0xaf,
53 0x48, 0x22, 0x12, 0x45, 0x2e, 0xf5, 0xf, 0x87, 0x92, 0xe2,
54 0x84, 0x1, 0xf9, 0x12, 0xf, 0x14, 0x15, 0x24, 0xce, 0x89,
55 0x99, 0xee, 0xb9, 0xc4, 0x17, 0x70, 0x70, 0x15, 0xea, 0xbe,
56 0xc6, 0x6c, 0x1f, 0x62, 0xb3, 0xf4, 0x2d, 0x16, 0x87, 0xfb,
57 0x56, 0x1e, 0x45, 0xab, 0xae, 0x32, 0xe4, 0x5e, 0x91, 0xed,
58 0x53, 0x66, 0x5e, 0xbd, 0xed, 0xad, 0xe6, 0x12, 0x39, 0xd,
59 0x83, 0xc9, 0xe8, 0x6b, 0x6c, 0x2d, 0xa5, 0xee, 0xc4, 0x5a,
60 0x66, 0xae, 0x8c, 0x97, 0xd7, 0xd, 0x6c, 0x49, 0xc7, 0xf5,
61 0xc4, 0x92, 0x31, 0x8b, 0x9, 0xee, 0x33, 0xda, 0xa9, 0x37,
62 0xb6, 0x49, 0x18, 0xf8, 0xe, 0x60, 0x45, 0xc8, 0x33, 0x91,
63 0xef, 0x20, 0x57, 0x10, 0xbe, 0x78, 0x2d, 0x83, 0x26, 0xd6,
64 0xca, 0x61, 0xf9, 0x2f, 0xe0, 0xbf, 0x5, 0x30, 0x52, 0x5a,
65 0x12, 0x1c, 0x0, 0xa7, 0x5d, 0xcc, 0x7c, 0x2e, 0xc5, 0x95,
66 0x8b, 0xa3, 0x3b, 0xf0, 0x43, 0x2e, 0x5e, 0xdd, 0x0, 0xdb,
67 0xd, 0xb3, 0x37, 0x99, 0xa9, 0xcd, 0x9c, 0xb7, 0x43, 0xf7,
68 0x35, 0x44, 0x21, 0xc2, 0x82, 0x71, 0xab, 0x8d, 0xaa, 0xb4,
69 0x41, 0x11, 0xec, 0x1e, 0x8d, 0xfc, 0x14, 0x82, 0x92, 0x4e,
70 0x83, 0x6a, 0xa, 0x6b, 0x35, 0x5e, 0x5d, 0xe9, 0x5c, 0xcc,
71 0x8c, 0xde, 0x39, 0xd1, 0x4a, 0x5b, 0x5f, 0x63, 0xa9, 0x64,
72 0xe0, 0xa, 0xcb, 0xb, 0xb8, 0x5a, 0x7c, 0xc3, 0xb, 0xe6,
73 0xbe, 0xfe, 0x8b, 0xf, 0x7d, 0x34, 0x8e, 0x2, 0x66, 0x74,
74 0x1, 0x6c, 0xca, 0x76, 0xac, 0x7c, 0x67, 0x8, 0x2f, 0x3f,
75 0x1a, 0xa6, 0x2c, 0x60, 0xb3, 0xff, 0xda, 0x8d, 0xb8, 0x12,
76 0xc, 0x0, 0x7f, 0xcc, 0x50, 0xa1, 0x5c, 0x64, 0xa1, 0xe2,
77 0x5f, 0x32, 0x65, 0xc9, 0x9c, 0xbe, 0xd6, 0xa, 0x13, 0x87,
78 0x3c, 0x2a, 0x45, 0x47, 0xc, 0xca, 0x42, 0x82, 0xfa, 0x89,
79 0x65, 0xe7, 0x89, 0xb4, 0x8f, 0xf7, 0x1e, 0xe6, 0x23, 0xa5,
80 0xd0, 0x59, 0x37, 0x79, 0x92, 0xd7, 0xce, 0x3d, 0xfd, 0xe3,
81 0xa1, 0xb, 0xcf, 0x6c, 0x85, 0xa0, 0x65, 0xf3, 0x5c, 0xc6,
82 0x4a, 0x63, 0x5f, 0x6e, 0x3a, 0x3a, 0x2a, 0x8b, 0x6a, 0xb6,
83 0x2f, 0xbb, 0xf8, 0xb2, 0x4b, 0x62, 0xbc, 0x1a, 0x91, 0x25,
84 0x66, 0xe3, 0x69, 0xca, 0x60, 0x49, 0xb, 0xf6, 0x8a, 0xbe,
85 0x3e, 0x76, 0x53, 0xc2, 0x7a, 0xa8, 0x4, 0x17, 0x75, 0xf1,
86 0xf3, 0x3, 0x62, 0x1b, 0x85, 0xb2, 0xb0, 0xef, 0x80, 0x15,
87 0xb6, 0xd4, 0x4e, 0xdf, 0x71, 0xac, 0xdb, 0x2a, 0x4, 0xd4,
88 0xb4, 0x21, 0xba, 0x65, 0x56, 0x57, 0xe8, 0xfa, 0x84, 0xa2,
89 0x7d, 0x13, 0xe, 0xaf, 0xd7, 0x9a, 0x58, 0x2a, 0xa3, 0x81,
90 0x84, 0x8d, 0x9, 0xa0, 0x6a, 0xc1, 0xbb, 0xd9, 0xf5, 0x86,
91 0xac, 0xbd, 0x75, 0x61, 0x9, 0xe6, 0x8c, 0x3d, 0x77, 0xb2,
92 0xed, 0x30, 0x20, 0xe4, 0x0, 0x1d, 0x97, 0xe8, 0xbf, 0xc7,
93 0x0, 0x1b, 0x21, 0xb1, 0x16, 0xe7, 0x41, 0x67, 0x2e, 0xec,
94 0x38, 0xbc, 0xe5, 0x1b, 0xb4, 0x6, 0x23, 0x31, 0x71, 0x1c,
95 0x49, 0xcd, 0x76, 0x4a, 0x76, 0x36, 0x8d, 0xa3, 0x89, 0x8b,
96 0x4a, 0x7a, 0xf4, 0x87, 0xc8, 0x15, 0xf, 0x37, 0x39, 0xf6,
97 0x6d, 0x80, 0x19, 0xef, 0x5c, 0xa8, 0x66, 0xce, 0x1b, 0x16,
98 0x79, 0x21, 0xdf, 0xd7, 0x31, 0x30, 0xc4, 0x21, 0xdd, 0x34,
99 0x5b, 0xd2, 0x1a, 0x2b, 0x3e, 0x5d, 0xf7, 0xea, 0xca, 0x5,
100 0x8e, 0xb7, 0xcb, 0x49, 0x2e, 0xa0, 0xe3, 0xf4, 0xa7, 0x48,
101 0x19, 0x10, 0x9c, 0x4, 0xa7, 0xf4, 0x28, 0x74, 0xc8, 0x6f,
102 0x63, 0x20, 0x2b, 0x46, 0x24, 0x26, 0x19, 0x1d, 0xd1, 0x2c,
103 0x31, 0x6d, 0x5a, 0x29, 0xa2, 0x6, 0xa6, 0xb2, 0x41, 0xcc,
104 0xa, 0x27, 0x96, 0x9, 0x96, 0xac, 0x47, 0x65, 0x78, 0x68,
105 0x51, 0x98, 0xd6, 0xd8, 0xa6, 0x2d, 0xa0, 0xcf, 0xec, 0xe2,
106 0x74, 0xf2, 0x82, 0xe3, 0x97, 0xd9, 0x7e, 0xd4, 0xf8, 0xb,
107 0x70, 0x43, 0x3d, 0xb1, 0x7b, 0x97, 0x80, 0xd6, 0xcb, 0xd7,
108 0x19, 0xbc, 0x63, 0xb, 0xfd, 0x4d, 0x88, 0xfe, 0x67, 0xac,
109 0xb8, 0xcc, 0x50, 0xb7, 0x68, 0xb3, 0x5b, 0xd6, 0x1e, 0x25,
110 0xfc, 0x5f, 0x3c, 0x8d, 0xb1, 0x33, 0x7c, 0xb3, 0x49, 0x1,
111 0x3f, 0x71, 0x55, 0xe, 0x51, 0xba, 0x61, 0x26, 0xfa, 0xea,
112 0xe5, 0xb5, 0xe8, 0xaa, 0xcf, 0xcd, 0x96, 0x9f, 0xd6, 0xc1,
113 0x5f, 0x53, 0x91, 0xad, 0x5, 0xde, 0x20, 0xe7, 0x51, 0xda,
114 0x5b, 0x95, 0x67, 0xed, 0xf4, 0xee, 0x42, 0x65, 0x70, 0x13,
115 0xb, 0x70, 0x14, 0x1c, 0xc9, 0xe0, 0x19, 0xca, 0x5f, 0xf5,
116 0x1d, 0x70, 0x4b, 0x6c, 0x6, 0x74, 0xec, 0xb5, 0x2e, 0x77,
117 0xe1, 0x74, 0xa1, 0xa3, 0x99, 0xa0, 0x85, 0x9e, 0xf1, 0xac,
122 * ============================================================================
123 * Boot states support (GREEN, YELLOW, ORANGE, RED) and dm_verity
124 * ============================================================================
126 char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state)
128 struct AvbOpsData *data;
129 char *cmdline = NULL;
134 data = (struct AvbOpsData *)ops->user_data;
138 data->boot_state = boot_state;
139 switch (boot_state) {
141 cmdline = "androidboot.verifiedbootstate=green";
144 cmdline = "androidboot.verifiedbootstate=yellow";
147 cmdline = "androidboot.verifiedbootstate=orange";
155 char *append_cmd_line(char *cmdline_orig, char *cmdline_new)
163 cmd_line = cmdline_orig;
167 cmd_line = avb_strdupv(cmd_line, " ", cmdline_new, NULL);
172 static int avb_find_dm_args(char **args, char *str)
179 for (i = 0; i < AVB_MAX_ARGS && args[i]; ++i) {
180 if (strstr(args[i], str))
187 static char *avb_set_enforce_option(const char *cmdline, const char *option)
189 char *cmdarg[AVB_MAX_ARGS];
190 char *newargs = NULL;
194 memset(cmdarg, 0, sizeof(cmdarg));
195 cmdarg[i++] = strtok((char *)cmdline, " ");
198 cmdarg[i] = strtok(NULL, " ");
202 if (++i >= AVB_MAX_ARGS) {
203 printf("%s: Can't handle more then %d args\n",
210 i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_LOGGING);
212 cmdarg[i] = (char *)option;
214 i = avb_find_dm_args(&cmdarg[0], VERITY_TABLE_OPT_RESTART);
216 printf("%s: No verity options found\n", __func__);
220 cmdarg[i] = (char *)option;
223 for (i = 0; i <= total_args; i++)
224 newargs = append_cmd_line(newargs, cmdarg[i]);
229 char *avb_set_ignore_corruption(const char *cmdline)
231 char *newargs = NULL;
233 newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_LOGGING);
235 newargs = append_cmd_line(newargs,
236 "androidboot.veritymode=eio");
241 char *avb_set_enforce_verity(const char *cmdline)
245 newargs = avb_set_enforce_option(cmdline, VERITY_TABLE_OPT_RESTART);
247 newargs = append_cmd_line(newargs,
248 "androidboot.veritymode=enforcing");
253 * ============================================================================
254 * IO(mmc) auxiliary functions
255 * ============================================================================
257 static unsigned long mmc_read_and_flush(struct mmc_part *part,
265 bool unaligned = is_buf_unaligned(buffer);
267 if (start < part->info.start) {
268 printf("%s: partition start out of bounds\n", __func__);
271 if ((start + sectors) > (part->info.start + part->info.size)) {
272 sectors = part->info.start + part->info.size - start;
273 printf("%s: read sector aligned to partition bounds (%ld)\n",
278 * Reading fails on unaligned buffers, so we have to
279 * use aligned temporary buffer and then copy to destination
283 printf("Handling unaligned read buffer..\n");
284 tmp_buf = get_sector_buf();
285 buf_size = get_sector_buf_size();
286 if (sectors > buf_size / part->info.blksz)
287 sectors = buf_size / part->info.blksz;
292 blks = blk_dread(part->mmc_blk,
293 start, sectors, tmp_buf);
294 /* flush cache after read */
295 flush_cache((ulong)tmp_buf, sectors * part->info.blksz);
298 memcpy(buffer, tmp_buf, sectors * part->info.blksz);
303 static unsigned long mmc_write(struct mmc_part *part, lbaint_t start,
304 lbaint_t sectors, void *buffer)
308 bool unaligned = is_buf_unaligned(buffer);
310 if (start < part->info.start) {
311 printf("%s: partition start out of bounds\n", __func__);
314 if ((start + sectors) > (part->info.start + part->info.size)) {
315 sectors = part->info.start + part->info.size - start;
316 printf("%s: sector aligned to partition bounds (%ld)\n",
320 tmp_buf = get_sector_buf();
321 buf_size = get_sector_buf_size();
322 printf("Handling unaligned wrire buffer..\n");
323 if (sectors > buf_size / part->info.blksz)
324 sectors = buf_size / part->info.blksz;
326 memcpy(tmp_buf, buffer, sectors * part->info.blksz);
331 return blk_dwrite(part->mmc_blk,
332 start, sectors, tmp_buf);
335 static struct mmc_part *get_partition(AvbOps *ops, const char *partition)
340 struct mmc_part *part;
341 struct blk_desc *mmc_blk;
343 part = malloc(sizeof(struct mmc_part));
347 dev_num = get_boot_device(ops);
348 part->mmc = find_mmc_device(dev_num);
350 printf("No MMC device at slot %x\n", dev_num);
354 if (mmc_init(part->mmc)) {
355 printf("MMC initialization failed\n");
359 ret = mmc_switch_part(part->mmc, part_num);
363 mmc_blk = mmc_get_blk_desc(part->mmc);
365 printf("Error - failed to obtain block descriptor\n");
369 ret = part_get_info_by_name(mmc_blk, partition, &part->info);
371 printf("Can't find partition '%s'\n", partition);
375 part->dev_num = dev_num;
376 part->mmc_blk = mmc_blk;
384 static AvbIOResult mmc_byte_io(AvbOps *ops,
385 const char *partition,
389 size_t *out_num_read,
390 enum mmc_io_type io_type)
393 struct mmc_part *part;
394 u64 start_offset, start_sector, sectors, residue;
398 if (!partition || !buffer || io_type > IO_WRITE)
399 return AVB_IO_RESULT_ERROR_IO;
401 part = get_partition(ops, partition);
403 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
405 if (!part->info.blksz)
406 return AVB_IO_RESULT_ERROR_IO;
408 start_offset = calc_offset(part, offset);
410 start_sector = start_offset / part->info.blksz;
411 sectors = num_bytes / part->info.blksz;
412 /* handle non block-aligned reads */
413 if (start_offset % part->info.blksz ||
414 num_bytes < part->info.blksz) {
415 tmp_buf = get_sector_buf();
416 if (start_offset % part->info.blksz) {
417 residue = part->info.blksz -
418 (start_offset % part->info.blksz);
419 if (residue > num_bytes)
425 if (io_type == IO_READ) {
426 ret = mmc_read_and_flush(part,
432 printf("%s: read error (%ld, %lld)\n",
433 __func__, ret, start_sector);
434 return AVB_IO_RESULT_ERROR_IO;
437 * if this is not aligned at sector start,
438 * we have to adjust the tmp buffer
440 tmp_buf += (start_offset % part->info.blksz);
441 memcpy(buffer, (void *)tmp_buf, residue);
443 ret = mmc_read_and_flush(part,
449 printf("%s: read error (%ld, %lld)\n",
450 __func__, ret, start_sector);
451 return AVB_IO_RESULT_ERROR_IO;
453 memcpy((void *)tmp_buf +
454 start_offset % part->info.blksz,
457 ret = mmc_write(part, part->info.start +
458 start_sector, 1, tmp_buf);
460 printf("%s: write error (%ld, %lld)\n",
461 __func__, ret, start_sector);
462 return AVB_IO_RESULT_ERROR_IO;
468 start_offset += residue;
469 num_bytes -= residue;
474 if (io_type == IO_READ) {
475 ret = mmc_read_and_flush(part,
480 ret = mmc_write(part,
487 printf("%s: sector read error\n", __func__);
488 return AVB_IO_RESULT_ERROR_IO;
491 io_cnt += ret * part->info.blksz;
492 buffer += ret * part->info.blksz;
493 start_offset += ret * part->info.blksz;
494 num_bytes -= ret * part->info.blksz;
498 /* Set counter for read operation */
499 if (io_type == IO_READ && out_num_read)
500 *out_num_read = io_cnt;
502 return AVB_IO_RESULT_OK;
506 * ============================================================================
508 * ============================================================================
512 * read_from_partition() - reads @num_bytes from @offset from partition
513 * identified by a string name
515 * @ops: contains AVB ops handlers
516 * @partition_name: partition name, NUL-terminated UTF-8 string
517 * @offset: offset from the beginning of partition
518 * @num_bytes: amount of bytes to read
519 * @buffer: destination buffer to store data
523 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
524 * AVB_IO_RESULT_ERROR_IO, if i/o error occurred from the underlying i/o
526 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if there is no partition with
529 static AvbIOResult read_from_partition(AvbOps *ops,
530 const char *partition_name,
531 s64 offset_from_partition,
534 size_t *out_num_read)
536 return mmc_byte_io(ops, partition_name, offset_from_partition,
537 num_bytes, buffer, out_num_read, IO_READ);
541 * write_to_partition() - writes N bytes to a partition identified by a string
544 * @ops: AvbOps, contains AVB ops handlers
545 * @partition_name: partition name
546 * @offset_from_partition: offset from the beginning of partition
547 * @num_bytes: amount of bytes to write
548 * @buf: data to write
552 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
553 * AVB_IO_RESULT_ERROR_IO, if input/output error occurred
554 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition, specified in
555 * @partition_name was not found
557 static AvbIOResult write_to_partition(AvbOps *ops,
558 const char *partition_name,
559 s64 offset_from_partition,
563 return mmc_byte_io(ops, partition_name, offset_from_partition,
564 num_bytes, (void *)buffer, NULL, IO_WRITE);
568 * validate_vmbeta_public_key() - checks if the given public key used to sign
569 * the vbmeta partition is trusted
571 * @ops: AvbOps, contains AVB ops handlers
572 * @public_key_data: public key for verifying vbmeta partition signature
573 * @public_key_length: length of public key
574 * @public_key_metadata:
575 * @public_key_metadata_length:
576 * @out_key_is_trusted:
579 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
581 static AvbIOResult validate_vbmeta_public_key(AvbOps *ops,
582 const u8 *public_key_data,
583 size_t public_key_length,
585 *public_key_metadata,
587 public_key_metadata_length,
588 bool *out_key_is_trusted)
590 if (!public_key_length || !public_key_data || !out_key_is_trusted)
591 return AVB_IO_RESULT_ERROR_IO;
593 *out_key_is_trusted = false;
594 if (public_key_length != sizeof(avb_root_pub))
595 return AVB_IO_RESULT_ERROR_IO;
597 if (memcmp(avb_root_pub, public_key_data, public_key_length) == 0)
598 *out_key_is_trusted = true;
600 return AVB_IO_RESULT_OK;
604 * read_rollback_index() - gets the rollback index corresponding to the
605 * location of given by @out_rollback_index.
607 * @ops: contains AvbOps handlers
608 * @rollback_index_slot:
609 * @out_rollback_index: used to write a retrieved rollback index.
612 * AVB_IO_RESULT_OK, if the roolback index was retrieved
614 static AvbIOResult read_rollback_index(AvbOps *ops,
615 size_t rollback_index_slot,
616 u64 *out_rollback_index)
618 /* For now we always return 0 as the stored rollback index. */
619 printf("%s not supported yet\n", __func__);
621 if (out_rollback_index)
622 *out_rollback_index = 0;
624 return AVB_IO_RESULT_OK;
628 * write_rollback_index() - sets the rollback index corresponding to the
629 * location of given by @out_rollback_index.
631 * @ops: contains AvbOps handlers
632 * @rollback_index_slot:
633 * @rollback_index: rollback index to write.
636 * AVB_IO_RESULT_OK, if the roolback index was retrieved
638 static AvbIOResult write_rollback_index(AvbOps *ops,
639 size_t rollback_index_slot,
642 /* For now this is a no-op. */
643 printf("%s not supported yet\n", __func__);
645 return AVB_IO_RESULT_OK;
649 * read_is_device_unlocked() - gets whether the device is unlocked
651 * @ops: contains AVB ops handlers
652 * @out_is_unlocked: device unlock state is stored here, true if unlocked,
656 * AVB_IO_RESULT_OK: state is retrieved successfully
657 * AVB_IO_RESULT_ERROR_IO: an error occurred
659 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
661 /* For now we always return that the device is unlocked. */
663 printf("%s not supported yet\n", __func__);
665 *out_is_unlocked = true;
667 return AVB_IO_RESULT_OK;
671 * get_unique_guid_for_partition() - gets the GUID for a partition identified
674 * @ops: contains AVB ops handlers
675 * @partition: partition name (NUL-terminated UTF-8 string)
676 * @guid_buf: buf, used to copy in GUID string. Example of value:
677 * 527c1c6d-6361-4593-8842-3c78fcd39219
678 * @guid_buf_size: @guid_buf buffer size
681 * AVB_IO_RESULT_OK, on success (GUID found)
682 * AVB_IO_RESULT_ERROR_IO, if incorrect buffer size (@guid_buf_size) was
684 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found
686 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
687 const char *partition,
689 size_t guid_buf_size)
691 struct mmc_part *part;
694 part = get_partition(ops, partition);
696 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
698 uuid_size = sizeof(part->info.uuid);
699 if (uuid_size > guid_buf_size)
700 return AVB_IO_RESULT_ERROR_IO;
702 memcpy(guid_buf, part->info.uuid, uuid_size);
703 guid_buf[uuid_size - 1] = 0;
705 return AVB_IO_RESULT_OK;
709 * get_size_of_partition() - gets the size of a partition identified
712 * @ops: contains AVB ops handlers
713 * @partition: partition name (NUL-terminated UTF-8 string)
714 * @out_size_num_bytes: returns the value of a partition size
717 * AVB_IO_RESULT_OK, on success (GUID found)
718 * AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE, out_size_num_bytes is NULL
719 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found
721 static AvbIOResult get_size_of_partition(AvbOps *ops,
722 const char *partition,
723 u64 *out_size_num_bytes)
725 struct mmc_part *part;
727 if (!out_size_num_bytes)
728 return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
730 part = get_partition(ops, partition);
732 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
734 *out_size_num_bytes = part->info.blksz * part->info.size;
736 return AVB_IO_RESULT_OK;
740 * ============================================================================
741 * AVB2.0 AvbOps alloc/initialisation/free
742 * ============================================================================
744 AvbOps *avb_ops_alloc(int boot_device)
746 struct AvbOpsData *ops_data;
748 ops_data = avb_calloc(sizeof(struct AvbOpsData));
752 ops_data->ops.user_data = ops_data;
754 ops_data->ops.read_from_partition = read_from_partition;
755 ops_data->ops.write_to_partition = write_to_partition;
756 ops_data->ops.validate_vbmeta_public_key = validate_vbmeta_public_key;
757 ops_data->ops.read_rollback_index = read_rollback_index;
758 ops_data->ops.write_rollback_index = write_rollback_index;
759 ops_data->ops.read_is_device_unlocked = read_is_device_unlocked;
760 ops_data->ops.get_unique_guid_for_partition =
761 get_unique_guid_for_partition;
762 ops_data->ops.get_size_of_partition = get_size_of_partition;
763 ops_data->mmc_dev = boot_device;
765 return &ops_data->ops;
768 void avb_ops_free(AvbOps *ops)
770 struct AvbOpsData *ops_data;
775 ops_data = ops->user_data;