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 start_offset = calc_offset(part, offset);
407 start_sector = start_offset / part->info.blksz;
408 sectors = num_bytes / part->info.blksz;
409 /* handle non block-aligned reads */
410 if (start_offset % part->info.blksz ||
411 num_bytes < part->info.blksz) {
412 tmp_buf = get_sector_buf();
413 if (start_offset % part->info.blksz) {
414 residue = part->info.blksz -
415 (start_offset % part->info.blksz);
416 if (residue > num_bytes)
422 if (io_type == IO_READ) {
423 ret = mmc_read_and_flush(part,
429 printf("%s: read error (%ld, %lld)\n",
430 __func__, ret, start_sector);
431 return AVB_IO_RESULT_ERROR_IO;
434 * if this is not aligned at sector start,
435 * we have to adjust the tmp buffer
437 tmp_buf += (start_offset % part->info.blksz);
438 memcpy(buffer, (void *)tmp_buf, residue);
440 ret = mmc_read_and_flush(part,
446 printf("%s: read error (%ld, %lld)\n",
447 __func__, ret, start_sector);
448 return AVB_IO_RESULT_ERROR_IO;
450 memcpy((void *)tmp_buf +
451 start_offset % part->info.blksz,
454 ret = mmc_write(part, part->info.start +
455 start_sector, 1, tmp_buf);
457 printf("%s: write error (%ld, %lld)\n",
458 __func__, ret, start_sector);
459 return AVB_IO_RESULT_ERROR_IO;
465 start_offset += residue;
466 num_bytes -= residue;
471 if (io_type == IO_READ) {
472 ret = mmc_read_and_flush(part,
477 ret = mmc_write(part,
484 printf("%s: sector read error\n", __func__);
485 return AVB_IO_RESULT_ERROR_IO;
488 io_cnt += ret * part->info.blksz;
489 buffer += ret * part->info.blksz;
490 start_offset += ret * part->info.blksz;
491 num_bytes -= ret * part->info.blksz;
495 /* Set counter for read operation */
496 if (io_type == IO_READ && out_num_read)
497 *out_num_read = io_cnt;
499 return AVB_IO_RESULT_OK;
503 * ============================================================================
505 * ============================================================================
509 * read_from_partition() - reads @num_bytes from @offset from partition
510 * identified by a string name
512 * @ops: contains AVB ops handlers
513 * @partition_name: partition name, NUL-terminated UTF-8 string
514 * @offset: offset from the beginning of partition
515 * @num_bytes: amount of bytes to read
516 * @buffer: destination buffer to store data
520 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
521 * AVB_IO_RESULT_ERROR_IO, if i/o error occurred from the underlying i/o
523 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if there is no partition with
526 static AvbIOResult read_from_partition(AvbOps *ops,
527 const char *partition_name,
528 s64 offset_from_partition,
531 size_t *out_num_read)
533 return mmc_byte_io(ops, partition_name, offset_from_partition,
534 num_bytes, buffer, out_num_read, IO_READ);
538 * write_to_partition() - writes N bytes to a partition identified by a string
541 * @ops: AvbOps, contains AVB ops handlers
542 * @partition_name: partition name
543 * @offset_from_partition: offset from the beginning of partition
544 * @num_bytes: amount of bytes to write
545 * @buf: data to write
549 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
550 * AVB_IO_RESULT_ERROR_IO, if input/output error occurred
551 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition, specified in
552 * @partition_name was not found
554 static AvbIOResult write_to_partition(AvbOps *ops,
555 const char *partition_name,
556 s64 offset_from_partition,
560 return mmc_byte_io(ops, partition_name, offset_from_partition,
561 num_bytes, (void *)buffer, NULL, IO_WRITE);
565 * validate_vmbeta_public_key() - checks if the given public key used to sign
566 * the vbmeta partition is trusted
568 * @ops: AvbOps, contains AVB ops handlers
569 * @public_key_data: public key for verifying vbmeta partition signature
570 * @public_key_length: length of public key
571 * @public_key_metadata:
572 * @public_key_metadata_length:
573 * @out_key_is_trusted:
576 * AVB_IO_RESULT_OK, if partition was found and read operation succeed
578 static AvbIOResult validate_vbmeta_public_key(AvbOps *ops,
579 const u8 *public_key_data,
580 size_t public_key_length,
582 *public_key_metadata,
584 public_key_metadata_length,
585 bool *out_key_is_trusted)
587 if (!public_key_length || !public_key_data || !out_key_is_trusted)
588 return AVB_IO_RESULT_ERROR_IO;
590 *out_key_is_trusted = false;
591 if (public_key_length != sizeof(avb_root_pub))
592 return AVB_IO_RESULT_ERROR_IO;
594 if (memcmp(avb_root_pub, public_key_data, public_key_length) == 0)
595 *out_key_is_trusted = true;
597 return AVB_IO_RESULT_OK;
601 * read_rollback_index() - gets the rollback index corresponding to the
602 * location of given by @out_rollback_index.
604 * @ops: contains AvbOps handlers
605 * @rollback_index_slot:
606 * @out_rollback_index: used to write a retrieved rollback index.
609 * AVB_IO_RESULT_OK, if the roolback index was retrieved
611 static AvbIOResult read_rollback_index(AvbOps *ops,
612 size_t rollback_index_slot,
613 u64 *out_rollback_index)
615 /* For now we always return 0 as the stored rollback index. */
616 printf("%s not supported yet\n", __func__);
618 if (out_rollback_index)
619 *out_rollback_index = 0;
621 return AVB_IO_RESULT_OK;
625 * write_rollback_index() - sets the rollback index corresponding to the
626 * location of given by @out_rollback_index.
628 * @ops: contains AvbOps handlers
629 * @rollback_index_slot:
630 * @rollback_index: rollback index to write.
633 * AVB_IO_RESULT_OK, if the roolback index was retrieved
635 static AvbIOResult write_rollback_index(AvbOps *ops,
636 size_t rollback_index_slot,
639 /* For now this is a no-op. */
640 printf("%s not supported yet\n", __func__);
642 return AVB_IO_RESULT_OK;
646 * read_is_device_unlocked() - gets whether the device is unlocked
648 * @ops: contains AVB ops handlers
649 * @out_is_unlocked: device unlock state is stored here, true if unlocked,
653 * AVB_IO_RESULT_OK: state is retrieved successfully
654 * AVB_IO_RESULT_ERROR_IO: an error occurred
656 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
658 /* For now we always return that the device is unlocked. */
660 printf("%s not supported yet\n", __func__);
662 *out_is_unlocked = true;
664 return AVB_IO_RESULT_OK;
668 * get_unique_guid_for_partition() - gets the GUID for a partition identified
671 * @ops: contains AVB ops handlers
672 * @partition: partition name (NUL-terminated UTF-8 string)
673 * @guid_buf: buf, used to copy in GUID string. Example of value:
674 * 527c1c6d-6361-4593-8842-3c78fcd39219
675 * @guid_buf_size: @guid_buf buffer size
678 * AVB_IO_RESULT_OK, on success (GUID found)
679 * AVB_IO_RESULT_ERROR_IO, if incorrect buffer size (@guid_buf_size) was
681 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found
683 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
684 const char *partition,
686 size_t guid_buf_size)
688 struct mmc_part *part;
691 part = get_partition(ops, partition);
693 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
695 uuid_size = sizeof(part->info.uuid);
696 if (uuid_size > guid_buf_size)
697 return AVB_IO_RESULT_ERROR_IO;
699 memcpy(guid_buf, part->info.uuid, uuid_size);
700 guid_buf[uuid_size - 1] = 0;
702 return AVB_IO_RESULT_OK;
706 * get_size_of_partition() - gets the size of a partition identified
709 * @ops: contains AVB ops handlers
710 * @partition: partition name (NUL-terminated UTF-8 string)
711 * @out_size_num_bytes: returns the value of a partition size
714 * AVB_IO_RESULT_OK, on success (GUID found)
715 * AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE, out_size_num_bytes is NULL
716 * AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION, if partition was not found
718 static AvbIOResult get_size_of_partition(AvbOps *ops,
719 const char *partition,
720 u64 *out_size_num_bytes)
722 struct mmc_part *part;
724 if (!out_size_num_bytes)
725 return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
727 part = get_partition(ops, partition);
729 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
731 *out_size_num_bytes = part->info.blksz * part->info.size;
733 return AVB_IO_RESULT_OK;
737 * ============================================================================
738 * AVB2.0 AvbOps alloc/initialisation/free
739 * ============================================================================
741 AvbOps *avb_ops_alloc(int boot_device)
743 struct AvbOpsData *ops_data;
745 ops_data = avb_calloc(sizeof(struct AvbOpsData));
749 ops_data->ops.user_data = ops_data;
751 ops_data->ops.read_from_partition = read_from_partition;
752 ops_data->ops.write_to_partition = write_to_partition;
753 ops_data->ops.validate_vbmeta_public_key = validate_vbmeta_public_key;
754 ops_data->ops.read_rollback_index = read_rollback_index;
755 ops_data->ops.write_rollback_index = write_rollback_index;
756 ops_data->ops.read_is_device_unlocked = read_is_device_unlocked;
757 ops_data->ops.get_unique_guid_for_partition =
758 get_unique_guid_for_partition;
759 ops_data->ops.get_size_of_partition = get_size_of_partition;
760 ops_data->mmc_dev = boot_device;
762 return &ops_data->ops;
765 void avb_ops_free(AvbOps *ops)
767 struct AvbOpsData *ops_data;
772 ops_data = ops->user_data;