• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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