xref: /rk3399_rockchip-uboot/lib/avb/libavb_user/avb_ops_user.c (revision 37a7bc39c0a3beca986e8c1c85d1dd6b9921e313)
1 /*
2  * Copyright (C) 2017 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 <common.h>
26 #include <image.h>
27 #include <android_image.h>
28 #include <malloc.h>
29 #include <mapmem.h>
30 #include <errno.h>
31 #include <command.h>
32 #include <mmc.h>
33 #include <blk.h>
34 #include <part.h>
35 #include <android_avb/avb_ops_user.h>
36 #include <android_avb/libavb_ab.h>
37 #include <android_avb/avb_atx_validate.h>
38 #include <android_avb/avb_atx_types.h>
39 #include <optee_include/OpteeClientInterface.h>
40 #include <optee_include/tee_api_defines.h>
41 #include <android_avb/avb_vbmeta_image.h>
42 #include <android_avb/avb_atx_validate.h>
43 
44 static void byte_to_block(int64_t *offset,
45 			  size_t *num_bytes,
46 			  lbaint_t *offset_blk,
47 			  lbaint_t *blkcnt)
48 {
49 	*offset_blk = (lbaint_t)(*offset / 512);
50 	if (*num_bytes % 512 == 0) {
51 		if (*offset % 512 == 0) {
52 			*blkcnt = (lbaint_t)(*num_bytes / 512);
53 		} else {
54 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
55 		}
56 	} else {
57 		if (*offset % 512 == 0) {
58 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
59 		} else {
60 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
61 			    (*offset % 512) + (*num_bytes % 512) == 512) {
62 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
63 			} else {
64 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
65 			}
66 		}
67 	}
68 }
69 
70 static AvbIOResult read_from_partition(AvbOps* ops,
71                                        const char* partition,
72                                        int64_t offset,
73                                        size_t num_bytes,
74                                        void* buffer,
75                                        size_t* out_num_read)
76 {
77 	char *dev_iface = "mmc";
78 	int dev_num = 0;
79 	struct blk_desc *dev_desc;
80 	lbaint_t offset_blk, blkcnt;
81 	disk_partition_t part_info;
82 
83 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
84 	dev_desc = blk_get_dev(dev_iface, dev_num);
85 	if (!dev_desc) {
86 		printf("Could not find %s %d\n", dev_iface, dev_num);
87 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
88 	}
89 
90 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
91 		printf("Could not find \"%s\" partition\n", partition);
92 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
93 	}
94 
95 	if((offset % 512 == 0) && (num_bytes % 512 == 0)) {
96 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
97 		*out_num_read = blkcnt * 512;
98 	} else {
99 		char *buffer_temp;
100 		buffer_temp = malloc(512 * blkcnt);
101 		if (buffer_temp == NULL) {
102 			printf("malloc error!\n");
103 			return AVB_IO_RESULT_ERROR_OOM;
104 		}
105 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp);
106 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
107 		*out_num_read = num_bytes;
108 		free(buffer_temp);
109 	}
110 
111 	return AVB_IO_RESULT_OK;
112 }
113 
114 static AvbIOResult write_to_partition(AvbOps* ops,
115                                       const char* partition,
116                                       int64_t offset,
117                                       size_t num_bytes,
118                                       const void* buffer)
119 {
120 	const char *dev_iface = "mmc";
121 	int dev_num = 0;
122 	struct blk_desc *dev_desc;
123 	char *buffer_temp;
124 	disk_partition_t part_info;
125 	lbaint_t offset_blk, blkcnt;
126 
127 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
128 	buffer_temp = malloc(512 * blkcnt);
129 	if (buffer_temp == NULL) {
130 		printf("malloc error!\n");
131 		return AVB_IO_RESULT_ERROR_OOM;
132 	}
133 	memset(buffer_temp, 0, 512 * blkcnt);
134 	dev_desc = blk_get_dev(dev_iface, dev_num);
135 	if (!dev_desc) {
136 		printf("Could not find %s %d\n", dev_iface, dev_num);
137 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
138 	}
139 
140 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
141 		printf("Could not find \"%s\" partition\n", partition);
142 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
143 	}
144 
145 	if ((offset % 512 != 0) && (num_bytes % 512) != 0) {
146 		blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp);
147 	}
148 
149 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
150 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
151 	free(buffer_temp);
152 
153 	return AVB_IO_RESULT_OK;
154 }
155 
156 static AvbIOResult validate_vbmeta_public_key(
157 	AvbOps *ops,
158 	const uint8_t *public_key_data,
159 	size_t public_key_length,
160 	const uint8_t *public_key_metadata,
161 	size_t public_key_metadata_length,
162 	bool *out_is_trusted)
163 {
164 #ifdef AVB_VBMETA_PUBLIC_KEY_VALIDATE
165 	if (out_is_trusted != NULL) {
166 		avb_atx_validate_vbmeta_public_key(ops,
167 						   public_key_data,
168 						   public_key_length,
169 						   public_key_metadata,
170 						   public_key_metadata_length,
171 						   out_is_trusted);
172 	}
173 #else
174 	if (out_is_trusted != NULL) {
175 		*out_is_trusted = true;
176 	}
177 #endif
178 	return AVB_IO_RESULT_OK;
179 }
180 
181 static AvbIOResult read_rollback_index(AvbOps *ops,
182                                        size_t rollback_index_location,
183                                        uint64_t *out_rollback_index)
184 {
185 	if (out_rollback_index != NULL) {
186 #ifdef CONFIG_OPTEE_CLIENT
187 		int ret;
188 		ret = trusty_read_rollback_index(rollback_index_location,
189 						 out_rollback_index);
190 		if (ret == TEE_ERROR_GENERIC) {
191 			*out_rollback_index = 0;
192 			ret = trusty_write_rollback_index(rollback_index_location,
193 							  *out_rollback_index);
194 			if (ret != 0) {
195 				printf("%s: init rollback index error\n", __FILE__);
196 				return AVB_IO_RESULT_ERROR_IO;
197 			}
198 			ret = trusty_read_rollback_index(rollback_index_location,
199 							 out_rollback_index);
200 			if (ret == 0)
201 				return AVB_IO_RESULT_OK;
202 		} else if (ret == 0) {
203 			return AVB_IO_RESULT_OK;
204 		} else {
205 			printf("trusty_read_rollback_index ret = %x\n", ret);
206 			return AVB_IO_RESULT_ERROR_IO;
207 		}
208 #endif
209 	}
210 	return AVB_IO_RESULT_ERROR_IO;
211 }
212 
213 static AvbIOResult write_rollback_index(AvbOps *ops,
214                                         size_t rollback_index_location,
215                                         uint64_t rollback_index)
216 {
217 #ifdef CONFIG_OPTEE_CLIENT
218 	if (trusty_write_rollback_index(rollback_index_location, rollback_index)) {
219 		printf("%s: Fail to write rollback index\n", __FILE__);
220 		return AVB_IO_RESULT_ERROR_IO;
221 	}
222 	return AVB_IO_RESULT_OK;
223 #endif
224 	return AVB_IO_RESULT_ERROR_IO;
225 }
226 
227 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
228 {
229 	if (out_is_unlocked != NULL) {
230 #ifdef CONFIG_OPTEE_CLIENT
231 		int ret;
232 
233 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
234 		if (ret == TEE_ERROR_GENERIC) {
235 			*out_is_unlocked = 1;
236 			if (trusty_write_lock_state(*out_is_unlocked)) {
237 				printf("%s: init lock state error\n", __FILE__);
238 				return AVB_IO_RESULT_ERROR_IO;
239 			}
240 
241 			ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
242 			if(ret == 0)
243 				return 0;
244 		} else if (ret == 0) {
245 			return AVB_IO_RESULT_OK;
246 		} else {
247 			printf("read_is_device_unlocked ret = %x\n", ret);
248 			return AVB_IO_RESULT_ERROR_IO;
249 		}
250 #endif
251 	}
252 	return AVB_IO_RESULT_ERROR_IO;
253 }
254 
255 static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
256 {
257 	if (out_is_unlocked != NULL) {
258 #ifdef CONFIG_OPTEE_CLIENT
259 		if (trusty_write_lock_state(*out_is_unlocked)) {
260 			printf("%s: Fail to write lock state\n", __FILE__);
261 			return AVB_IO_RESULT_ERROR_IO;
262 		}
263 		return AVB_IO_RESULT_OK;
264 #endif
265 	}
266 	return AVB_IO_RESULT_ERROR_IO;
267 }
268 
269 static AvbIOResult get_size_of_partition(AvbOps *ops,
270                                          const char *partition,
271                                          uint64_t *out_size_in_bytes)
272 {
273 	const char *dev_iface = "mmc";
274 	int dev_num = 0;
275 	struct blk_desc *dev_desc;
276 	disk_partition_t part_info;
277 
278 	dev_desc = blk_get_dev(dev_iface, dev_num);
279 	if (!dev_desc) {
280 		printf("Could not find %s %d\n", dev_iface, dev_num);
281 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
282 	}
283 
284 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
285 		printf("Could not find \"%s\" partition\n", partition);
286 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
287 	}
288 	*out_size_in_bytes = (part_info.size) * 512;
289 	return AVB_IO_RESULT_OK;
290 }
291 
292 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
293                                                  const char *partition,
294                                                  char *guid_buf,
295                                                  size_t guid_buf_size)
296 {
297 	const char *dev_iface = "mmc";
298 	int dev_num = 0;
299 	struct blk_desc *dev_desc;
300 	disk_partition_t part_info;
301 	dev_desc = blk_get_dev(dev_iface, dev_num);
302 	if (!dev_desc) {
303 		printf("Could not find %s %d\n", dev_iface, dev_num);
304 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
305 	}
306 
307 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
308 		printf("Could not find \"%s\" partition\n", partition);
309 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
310 	}
311 	if (guid_buf != NULL && guid_buf_size > 0) {
312 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
313 	}
314 	return AVB_IO_RESULT_OK;
315 }
316 
317 /* read permanent attributes from rpmb */
318 AvbIOResult avb_read_perm_attr(AvbAtxOps* atx_ops,
319 			       AvbAtxPermanentAttributes* attributes)
320 {
321 	if (attributes != NULL) {
322 #ifdef CONFIG_OPTEE_CLIENT
323 		trusty_read_permanent_attributes((uint8_t *)attributes,
324 						 sizeof(struct AvbAtxPermanentAttributes));
325 		return AVB_IO_RESULT_OK;
326 #endif
327 	}
328 
329 	return -1;
330 }
331 
332 /*read permanent attributes hash from efuse */
333 AvbIOResult avb_read_perm_attr_hash(AvbAtxOps* atx_ops,
334 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
335 {
336 #ifdef CONFIG_OPTEE_CLIENT
337 	if (trusty_read_attribute_hash((uint32_t *)hash, AVB_SHA256_DIGEST_SIZE / 4))
338 		return -1;
339 #else
340 	avb_error("Please open the macro!\n");
341 	return -1;
342 #endif
343 	return AVB_IO_RESULT_OK;
344 }
345 
346 AvbOps* avb_ops_user_new(void) {
347   AvbOps* ops;
348 
349   ops = calloc(1, sizeof(AvbOps));
350   if (ops == NULL) {
351     avb_error("Error allocating memory for AvbOps.\n");
352     goto out;
353   }
354 
355   ops->ab_ops = calloc(1, sizeof(AvbABOps));
356   if (ops->ab_ops == NULL) {
357     avb_error("Error allocating memory for AvbABOps.\n");
358     free(ops);
359     goto out;
360   }
361 
362   ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
363   if (ops->atx_ops == NULL) {
364     avb_error("Error allocating memory for AvbAtxOps.\n");
365     free(ops->ab_ops);
366     free(ops);
367     goto out;
368   }
369   ops->ab_ops->ops = ops;
370   ops->atx_ops->ops = ops;
371 
372   ops->read_from_partition = read_from_partition;
373   ops->write_to_partition = write_to_partition;
374   ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
375   ops->read_rollback_index = read_rollback_index;
376   ops->write_rollback_index = write_rollback_index;
377   ops->read_is_device_unlocked = read_is_device_unlocked;
378   ops->write_is_device_unlocked = write_is_device_unlocked;
379   ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
380   ops->get_size_of_partition = get_size_of_partition;
381   ops->ab_ops->read_ab_metadata = avb_ab_data_read;
382   ops->ab_ops->write_ab_metadata = avb_ab_data_write;
383   ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
384   ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
385 
386 out:
387   return ops;
388 }
389 
390 
391 void avb_ops_user_free(AvbOps* ops) {
392   free(ops->ab_ops);
393   free(ops->atx_ops);
394   free(ops);
395 }
396