1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * 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:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * 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.
23 */
24
25 #include "libavb_aftl/avb_aftl_verify.h"
26
27 #include <libavb/avb_cmdline.h>
28 #include <libavb/avb_slot_verify.h>
29 #include <libavb/avb_util.h>
30
31 #include "libavb_aftl/avb_aftl_types.h"
32 #include "libavb_aftl/avb_aftl_util.h"
33 #include "libavb_aftl/avb_aftl_validate.h"
34
35 /* Read the vbmeta partition, after the AvbVBMetaImageHeader structure, to find
36 * the AftlDescriptor.
37 */
avb_aftl_find_aftl_descriptor(AvbOps * ops,const char * part_name,size_t vbmeta_size,uint8_t * out_image_buf,size_t * out_image_size)38 static AvbSlotVerifyResult avb_aftl_find_aftl_descriptor(
39 AvbOps* ops,
40 const char* part_name,
41 size_t vbmeta_size,
42 uint8_t* out_image_buf,
43 size_t* out_image_size) {
44 AvbIOResult io_ret;
45
46 avb_assert(vbmeta_size <= AVB_AFTL_MAX_AFTL_DESCRIPTOR_SIZE);
47 io_ret =
48 ops->read_from_partition(ops,
49 part_name,
50 vbmeta_size /* offset */,
51 AVB_AFTL_MAX_AFTL_DESCRIPTOR_SIZE - vbmeta_size,
52 out_image_buf,
53 out_image_size);
54
55 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
56 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
57 } else if (io_ret != AVB_IO_RESULT_OK) {
58 avb_errorv(
59 part_name, ": Error loading AftlDescriptor from partition.\n", NULL);
60 return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
61 }
62
63 if (*out_image_size < 4 || (out_image_buf[0] != 'A') ||
64 (out_image_buf[1] != 'F') || (out_image_buf[2] != 'T') ||
65 (out_image_buf[3] != 'L')) {
66 avb_errorv(part_name, ": Unexpected AftlDescriptor magic.\n", NULL);
67 return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
68 }
69
70 return AVB_SLOT_VERIFY_RESULT_OK;
71 }
72
73 /* Performs the three validation steps for an AFTL descriptor:
74 1. Ensure the vbmeta image hash matches that in the descriptor.
75 2. Ensure the root hash of the Merkle tree matches that in the descriptor.
76 3. Verify the signature using the transparency log public key.
77 */
avb_aftl_verify_descriptor(uint8_t * cur_vbmeta_data,size_t cur_vbmeta_size,uint8_t * aftl_blob,size_t aftl_size,uint8_t * key_bytes,size_t key_num_bytes)78 static AvbSlotVerifyResult avb_aftl_verify_descriptor(uint8_t* cur_vbmeta_data,
79 size_t cur_vbmeta_size,
80 uint8_t* aftl_blob,
81 size_t aftl_size,
82 uint8_t* key_bytes,
83 size_t key_num_bytes) {
84 size_t i;
85 AftlDescriptor* aftl_descriptor;
86 AvbSlotVerifyResult result = AVB_SLOT_VERIFY_RESULT_OK;
87
88 /* Attempt to parse the AftlDescriptor pointed to by aftl_blob. */
89 aftl_descriptor = parse_aftl_descriptor(aftl_blob, aftl_size);
90 if (!aftl_descriptor) {
91 return AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
92 }
93
94 /* Now that a valid AftlDescriptor has been parsed, attempt to verify
95 the inclusion proof(s) in three steps. */
96 for (i = 0; i < aftl_descriptor->header.icp_count; i++) {
97 /* 1. Ensure that the vbmeta hash stored in the AftlIcpEntry matches
98 the one that represents the partition. */
99 if (!avb_aftl_verify_vbmeta_hash(
100 cur_vbmeta_data, cur_vbmeta_size, aftl_descriptor->entries[i])) {
101 avb_error("AFTL vbmeta hash verification failed.\n");
102 result = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
103 break;
104 }
105 /* 2. Ensure that the root hash of the Merkle tree representing
106 the transparency log entry matches the one stored in the
107 AftlIcpEntry. */
108 if (!avb_aftl_verify_icp_root_hash(aftl_descriptor->entries[i])) {
109 avb_error("AFTL root hash verification failed.\n");
110 result = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
111 break;
112 }
113 /* 3. Verify the signature using the transparency log public
114 key stored on device. */
115 if (!avb_aftl_verify_entry_signature(
116 key_bytes, key_num_bytes, aftl_descriptor->entries[i])) {
117 avb_error("AFTL signature verification failed on entry.\n");
118 result = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
119 break;
120 }
121 }
122 free_aftl_descriptor(aftl_descriptor);
123 return result;
124 }
125
aftl_slot_verify(AvbOps * ops,AvbSlotVerifyData * asv_data,uint8_t * key_bytes,size_t key_size)126 AvbSlotVerifyResult aftl_slot_verify(AvbOps* ops,
127 AvbSlotVerifyData* asv_data,
128 uint8_t* key_bytes,
129 size_t key_size) {
130 size_t i;
131 size_t aftl_descriptor_size;
132 size_t vbmeta_size;
133 uint8_t* current_aftl_blob;
134 char part_name[AVB_PART_NAME_MAX_SIZE];
135 char* pname;
136 AvbSlotVerifyResult ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
137
138 avb_assert(asv_data != NULL);
139 avb_assert(key_bytes != NULL);
140 avb_assert(key_size == AVB_AFTL_PUB_KEY_SIZE);
141 if (asv_data->vbmeta_images == NULL) {
142 return AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
143 }
144
145 current_aftl_blob = avb_malloc(AVB_AFTL_MAX_AFTL_DESCRIPTOR_SIZE);
146 if (current_aftl_blob == NULL) {
147 return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
148 }
149
150 /* Walk through each vbmeta blob in the AvbSlotVerifyData struct. */
151 for (i = 0; i < asv_data->num_vbmeta_images; i++) {
152 /* Rebuild partition name, appending the suffix */
153 pname = asv_data->vbmeta_images[i].partition_name;
154 if (!avb_str_concat(part_name,
155 sizeof part_name,
156 (const char*)pname,
157 avb_strlen(pname),
158 asv_data->ab_suffix,
159 avb_strlen(asv_data->ab_suffix))) {
160 avb_error("Partition name and suffix does not fit.\n");
161 ret = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
162 break;
163 }
164
165 /* Use the partition info to find the AftlDescriptor */
166 vbmeta_size = asv_data->vbmeta_images[i].vbmeta_size;
167 ret = avb_aftl_find_aftl_descriptor(
168 ops, part_name, vbmeta_size, current_aftl_blob, &aftl_descriptor_size);
169 if (ret != AVB_SLOT_VERIFY_RESULT_OK) {
170 avb_error("Unable to find the AftlDescriptor.\n");
171 ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
172 break;
173 }
174
175 /* Validate the AFTL descriptor in the vbmeta image. */
176 ret = avb_aftl_verify_descriptor(asv_data->vbmeta_images[i].vbmeta_data,
177 vbmeta_size,
178 current_aftl_blob,
179 aftl_descriptor_size,
180 key_bytes,
181 key_size);
182 if (ret != AVB_SLOT_VERIFY_RESULT_OK) break;
183 }
184
185 avb_free(current_aftl_blob);
186 return ret;
187 }
188