xref: /OK3568_Linux_fs/u-boot/lib/avb/libavb_user/avb_ops_user.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 <stdio.h>
36 #include <android_avb/avb_ops_user.h>
37 #include <android_avb/libavb_ab.h>
38 #include <android_avb/avb_atx_validate.h>
39 #include <android_avb/avb_atx_types.h>
40 #include <optee_include/OpteeClientInterface.h>
41 #include <optee_include/tee_api_defines.h>
42 #include <android_avb/avb_vbmeta_image.h>
43 #include <android_avb/avb_atx_validate.h>
44 #include <boot_rkimg.h>
45 
byte_to_block(int64_t * offset,size_t * num_bytes,lbaint_t * offset_blk,lbaint_t * blkcnt)46 static void byte_to_block(int64_t *offset,
47 			  size_t *num_bytes,
48 			  lbaint_t *offset_blk,
49 			  lbaint_t *blkcnt)
50 {
51 	*offset_blk = (lbaint_t)(*offset / 512);
52 	if (*num_bytes % 512 == 0) {
53 		if (*offset % 512 == 0)
54 			*blkcnt = (lbaint_t)(*num_bytes / 512);
55 		else
56 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
57 	} else {
58 		if (*offset % 512 == 0) {
59 			*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
60 		} else {
61 			if ((*offset % 512) + (*num_bytes % 512) < 512 ||
62 			    (*offset % 512) + (*num_bytes % 512) == 512) {
63 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 1;
64 			} else {
65 				*blkcnt = (lbaint_t)(*num_bytes / 512) + 2;
66 			}
67 		}
68 	}
69 }
70 
get_size_of_partition(AvbOps * ops,const char * partition,uint64_t * out_size_in_bytes)71 static AvbIOResult get_size_of_partition(AvbOps *ops,
72 					 const char *partition,
73 					 uint64_t *out_size_in_bytes)
74 {
75 	struct blk_desc *dev_desc;
76 	disk_partition_t part_info;
77 
78 	dev_desc = rockchip_get_bootdev();
79 	if (!dev_desc) {
80 		printf("%s: Could not find device\n", __func__);
81 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
82 	}
83 
84 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0)
85 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
86 
87 	*out_size_in_bytes = (part_info.size) * 512;
88 	return AVB_IO_RESULT_OK;
89 }
90 
read_from_partition(AvbOps * ops,const char * partition,int64_t offset,size_t num_bytes,void * buffer,size_t * out_num_read)91 static AvbIOResult read_from_partition(AvbOps *ops,
92 				       const char *partition,
93 				       int64_t offset,
94 				       size_t num_bytes,
95 				       void *buffer,
96 				       size_t *out_num_read)
97 {
98 	struct blk_desc *dev_desc;
99 	lbaint_t offset_blk, blkcnt;
100 	disk_partition_t part_info;
101 	uint64_t partition_size;
102 
103 	if (offset < 0) {
104 		if (get_size_of_partition(ops, partition, &partition_size))
105 			return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
106 
107 		if (-offset > partition_size)
108 			return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
109 
110 		offset = partition_size - (-offset);
111 	}
112 
113 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
114 	dev_desc = rockchip_get_bootdev();
115 	if (!dev_desc) {
116 		printf("%s: Could not find device\n", __func__);
117 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
118 	}
119 
120 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
121 		printf("Could not find \"%s\" partition\n", partition);
122 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
123 	}
124 
125 	if ((offset % 512 == 0) && (num_bytes % 512 == 0)) {
126 		blk_dread(dev_desc, part_info.start + offset_blk,
127 			  blkcnt, buffer);
128 		*out_num_read = blkcnt * 512;
129 	} else {
130 		char *buffer_temp;
131 
132 		buffer_temp = malloc(512 * blkcnt);
133 		if (!buffer_temp) {
134 			printf("malloc error!\n");
135 			return AVB_IO_RESULT_ERROR_OOM;
136 		}
137 		blk_dread(dev_desc, part_info.start + offset_blk,
138 			  blkcnt, buffer_temp);
139 		memcpy(buffer, buffer_temp + (offset % 512), num_bytes);
140 		*out_num_read = num_bytes;
141 		free(buffer_temp);
142 	}
143 
144 	return AVB_IO_RESULT_OK;
145 }
146 
write_to_partition(AvbOps * ops,const char * partition,int64_t offset,size_t num_bytes,const void * buffer)147 static AvbIOResult write_to_partition(AvbOps *ops,
148 				      const char *partition,
149 				      int64_t offset,
150 				      size_t num_bytes,
151 				      const void *buffer)
152 {
153 	struct blk_desc *dev_desc;
154 	char *buffer_temp;
155 	disk_partition_t part_info;
156 	lbaint_t offset_blk, blkcnt;
157 
158 	byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt);
159 	buffer_temp = malloc(512 * blkcnt);
160 	if (!buffer_temp) {
161 		printf("malloc error!\n");
162 		return AVB_IO_RESULT_ERROR_OOM;
163 	}
164 	memset(buffer_temp, 0, 512 * blkcnt);
165 	dev_desc = rockchip_get_bootdev();
166 	if (!dev_desc) {
167 		printf("%s: Could not find device\n", __func__);
168 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
169 	}
170 
171 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
172 		printf("Could not find \"%s\" partition\n", partition);
173 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
174 	}
175 
176 	if ((offset % 512 != 0) && (num_bytes % 512) != 0)
177 		blk_dread(dev_desc, part_info.start + offset_blk,
178 			  blkcnt, buffer_temp);
179 
180 	memcpy(buffer_temp, buffer + (offset % 512), num_bytes);
181 	blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer);
182 	free(buffer_temp);
183 
184 	return AVB_IO_RESULT_OK;
185 }
186 
187 static AvbIOResult
validate_vbmeta_public_key(AvbOps * ops,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_is_trusted)188 validate_vbmeta_public_key(AvbOps *ops,
189 			   const uint8_t *public_key_data,
190 			   size_t public_key_length,
191 			   const uint8_t *public_key_metadata,
192 			   size_t public_key_metadata_length,
193 			   bool *out_is_trusted)
194 {
195 /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
196 #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
197     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
198 	if (out_is_trusted) {
199 		avb_atx_validate_vbmeta_public_key(ops,
200 						   public_key_data,
201 						   public_key_length,
202 						   public_key_metadata,
203 						   public_key_metadata_length,
204 						   out_is_trusted);
205 	}
206 #else
207 	if (out_is_trusted)
208 		*out_is_trusted = true;
209 #endif
210 	return AVB_IO_RESULT_OK;
211 }
212 
read_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t * out_rollback_index)213 static AvbIOResult read_rollback_index(AvbOps *ops,
214 				       size_t rollback_index_location,
215 				       uint64_t *out_rollback_index)
216 {
217 	if (out_rollback_index) {
218 #ifdef CONFIG_OPTEE_CLIENT
219 		int ret;
220 
221 		ret = trusty_read_rollback_index(rollback_index_location,
222 						 out_rollback_index);
223 		switch (ret) {
224 		case TEE_SUCCESS:
225 			ret = AVB_IO_RESULT_OK;
226 			break;
227 		case TEE_ERROR_GENERIC:
228 		case TEE_ERROR_NO_DATA:
229 		case TEE_ERROR_ITEM_NOT_FOUND:
230 			*out_rollback_index = 0;
231 			ret = trusty_write_rollback_index(rollback_index_location,
232 							  *out_rollback_index);
233 			if (ret) {
234 				printf("%s: init rollback index error\n",
235 				       __FILE__);
236 				ret = AVB_IO_RESULT_ERROR_IO;
237 			} else {
238 				ret =
239 				trusty_read_rollback_index(rollback_index_location,
240 							   out_rollback_index);
241 				if (ret)
242 					ret = AVB_IO_RESULT_ERROR_IO;
243 				else
244 					ret = AVB_IO_RESULT_OK;
245 			}
246 			break;
247 		default:
248 			ret = AVB_IO_RESULT_ERROR_IO;
249 			printf("%s: trusty_read_rollback_index failed",
250 			       __FILE__);
251 		}
252 
253 		return ret;
254 #else
255 		*out_rollback_index = 0;
256 
257 		return AVB_IO_RESULT_OK;
258 #endif
259 	}
260 
261 	return AVB_IO_RESULT_ERROR_IO;
262 }
263 
write_rollback_index(AvbOps * ops,size_t rollback_index_location,uint64_t rollback_index)264 static AvbIOResult write_rollback_index(AvbOps *ops,
265 					size_t rollback_index_location,
266 					uint64_t rollback_index)
267 {
268 #ifdef CONFIG_OPTEE_CLIENT
269 	if (trusty_write_rollback_index(rollback_index_location,
270 					rollback_index)) {
271 		printf("%s: Fail to write rollback index\n", __FILE__);
272 		return AVB_IO_RESULT_ERROR_IO;
273 	}
274 	return AVB_IO_RESULT_OK;
275 #endif
276 	return AVB_IO_RESULT_ERROR_IO;
277 }
278 
read_is_device_unlocked(AvbOps * ops,bool * out_is_unlocked)279 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
280 {
281 	if (out_is_unlocked) {
282 #ifdef CONFIG_OPTEE_CLIENT
283 		uint8_t vboot_flag = 0;
284 		int ret;
285 
286 		ret = trusty_read_lock_state((uint8_t *)out_is_unlocked);
287 		switch (ret) {
288 		case TEE_SUCCESS:
289 			ret = AVB_IO_RESULT_OK;
290 			break;
291 		case TEE_ERROR_GENERIC:
292 		case TEE_ERROR_NO_DATA:
293 		case TEE_ERROR_ITEM_NOT_FOUND:
294 			if (trusty_read_vbootkey_enable_flag(&vboot_flag)) {
295 				printf("Can't read vboot flag\n");
296 				return AVB_IO_RESULT_ERROR_IO;
297 			}
298 
299 			if (vboot_flag)
300 				*out_is_unlocked = 0;
301 			else
302 				*out_is_unlocked = 1;
303 
304 			if (trusty_write_lock_state(*out_is_unlocked)) {
305 				printf("%s: init lock state error\n", __FILE__);
306 				ret = AVB_IO_RESULT_ERROR_IO;
307 			} else {
308 				ret =
309 				trusty_read_lock_state((uint8_t *)out_is_unlocked);
310 				if (ret == 0)
311 					ret = AVB_IO_RESULT_OK;
312 				else
313 					ret = AVB_IO_RESULT_ERROR_IO;
314 			}
315 			break;
316 		default:
317 			ret = AVB_IO_RESULT_ERROR_IO;
318 			printf("%s: trusty_read_lock_state failed\n", __FILE__);
319 		}
320 		return ret;
321 #else
322 		*out_is_unlocked = 1;
323 
324 		return AVB_IO_RESULT_OK;
325 #endif
326 	}
327 	return AVB_IO_RESULT_ERROR_IO;
328 }
329 
write_is_device_unlocked(AvbOps * ops,bool * out_is_unlocked)330 static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked)
331 {
332 	if (out_is_unlocked) {
333 #ifdef CONFIG_OPTEE_CLIENT
334 		if (trusty_write_lock_state(*out_is_unlocked)) {
335 			printf("%s: Fail to write lock state\n", __FILE__);
336 			return AVB_IO_RESULT_ERROR_IO;
337 		}
338 		return AVB_IO_RESULT_OK;
339 #endif
340 	}
341 	return AVB_IO_RESULT_ERROR_IO;
342 }
343 
get_unique_guid_for_partition(AvbOps * ops,const char * partition,char * guid_buf,size_t guid_buf_size)344 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops,
345 						 const char *partition,
346 						 char *guid_buf,
347 						 size_t guid_buf_size)
348 {
349 	struct blk_desc *dev_desc;
350 	disk_partition_t part_info;
351 
352 	dev_desc = rockchip_get_bootdev();
353 	if (!dev_desc) {
354 		printf("%s: Could not find device\n", __func__);
355 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
356 	}
357 
358 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
359 		printf("Could not find \"%s\" partition\n", partition);
360 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
361 	}
362 	if (guid_buf && guid_buf_size > 0)
363 		memcpy(guid_buf, part_info.uuid, guid_buf_size);
364 
365 	return AVB_IO_RESULT_OK;
366 }
367 
368 /* read permanent attributes from rpmb */
avb_read_perm_attr(AvbAtxOps * atx_ops,AvbAtxPermanentAttributes * attributes)369 AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops,
370 			       AvbAtxPermanentAttributes *attributes)
371 {
372 	if (attributes) {
373 #ifdef CONFIG_OPTEE_CLIENT
374 		trusty_read_permanent_attributes((uint8_t *)attributes,
375 						 sizeof(struct AvbAtxPermanentAttributes));
376 		return AVB_IO_RESULT_OK;
377 #endif
378 	}
379 
380 	return -1;
381 }
382 
383 /*read permanent attributes hash from efuse */
avb_read_perm_attr_hash(AvbAtxOps * atx_ops,uint8_t hash[AVB_SHA256_DIGEST_SIZE])384 AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops,
385 				    uint8_t hash[AVB_SHA256_DIGEST_SIZE])
386 {
387 #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
388 #ifdef CONFIG_OPTEE_CLIENT
389 	if (trusty_read_attribute_hash((uint32_t *)hash,
390 				       AVB_SHA256_DIGEST_SIZE / 4))
391 		return -1;
392 #else
393 	printf("Please open the macro!\n");
394 	return -1;
395 #endif
396 #endif
397 	return AVB_IO_RESULT_OK;
398 }
399 
avb_set_key_version(AvbAtxOps * atx_ops,size_t rollback_index_location,uint64_t key_version)400 static void avb_set_key_version(AvbAtxOps *atx_ops,
401 				size_t rollback_index_location,
402 				uint64_t key_version)
403 {
404 #ifdef CONFIG_OPTEE_CLIENT
405 	uint64_t key_version_temp = 0;
406 
407 	if (trusty_read_rollback_index(rollback_index_location, &key_version_temp))
408 		printf("%s: Fail to read rollback index\n", __FILE__);
409 	if (key_version_temp == key_version)
410 		return;
411 	if (trusty_write_rollback_index(rollback_index_location, key_version))
412 		printf("%s: Fail to write rollback index\n", __FILE__);
413 #endif
414 }
415 
rk_get_random(AvbAtxOps * atx_ops,size_t num_bytes,uint8_t * output)416 AvbIOResult rk_get_random(AvbAtxOps *atx_ops,
417 			  size_t num_bytes,
418 			  uint8_t *output)
419 {
420 	int i;
421 	unsigned int seed;
422 
423 	seed = (unsigned int)get_timer(0);
424 	for (i = 0; i < num_bytes; i++) {
425 		srand(seed);
426 		output[i] = (uint8_t)(rand());
427 		seed = (unsigned int)(output[i]);
428 	}
429 
430 	return 0;
431 }
432 
433 #ifdef CONFIG_ANDROID_BOOT_IMAGE
get_preloaded_partition(AvbOps * ops,const char * partition,size_t num_bytes,uint8_t ** out_pointer,size_t * out_num_bytes_preloaded,int allow_verification_error)434 static AvbIOResult get_preloaded_partition(AvbOps* ops,
435 					   const char* partition,
436 					   size_t num_bytes,
437 					   uint8_t** out_pointer,
438 					   size_t* out_num_bytes_preloaded,
439 					   int allow_verification_error)
440 {
441 	struct preloaded_partition *preload_info = NULL;
442 	struct AvbOpsData *data = ops->user_data;
443 	struct blk_desc *dev_desc;
444 	disk_partition_t part_info;
445 	ulong load_addr;
446 	AvbIOResult ret;
447 	int full_preload = 0;
448 
449 	dev_desc = rockchip_get_bootdev();
450 	if (!dev_desc)
451 		return AVB_IO_RESULT_ERROR_IO;
452 
453 	if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) {
454 		printf("Could not find \"%s\" partition\n", partition);
455 		return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
456 	}
457 
458 	if (!allow_verification_error) {
459 		if (!strncmp(partition, ANDROID_PARTITION_BOOT, 4) ||
460 		    !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8))
461 			preload_info = &data->boot;
462 		else if (!strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11))
463 			preload_info = &data->vendor_boot;
464 		else if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9))
465 			preload_info = &data->init_boot;
466 		else if (!strncmp(partition, ANDROID_PARTITION_RESOURCE, 8))
467 			preload_info = &data->resource;
468 
469 		if (!preload_info) {
470 			printf("Error: unknown full load partition '%s'\n", partition);
471 			return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
472 		}
473 
474 		printf("preloaded(s): %sfull image from '%s' at 0x%08lx - 0x%08lx\n",
475 		       preload_info->size ? "pre-" : "", partition,
476 		       (ulong)preload_info->addr,
477 		       (ulong)preload_info->addr + num_bytes);
478 
479 		/* If the partition hasn't yet been preloaded, do it now.*/
480 		if (preload_info->size == 0) {
481 			ret = ops->read_from_partition(ops, partition,
482 						       0, num_bytes,
483 						       preload_info->addr,
484 						       &preload_info->size);
485 			if (ret != AVB_IO_RESULT_OK)
486 				return ret;
487 		}
488 		*out_pointer = preload_info->addr;
489 		*out_num_bytes_preloaded = preload_info->size;
490 		ret = AVB_IO_RESULT_OK;
491 	} else {
492 		if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9) ||
493 		    !strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11) ||
494 		    !strncmp(partition, ANDROID_PARTITION_BOOT, 4) ||
495 		    !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8) ||
496 		    !strncmp(partition, ANDROID_PARTITION_RESOURCE, 8)) {
497 			/* If already full preloaded, just use it */
498 			if (!strncmp(partition, ANDROID_PARTITION_BOOT, 4) ||
499 			    !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8)) {
500 				preload_info = &data->boot;
501 				if (preload_info->size) {
502 					*out_pointer = preload_info->addr;
503 					*out_num_bytes_preloaded = num_bytes;
504 					full_preload = 1;
505 				}
506 			}
507 			printf("preloaded: %s image from '%s\n",
508 			       full_preload ? "pre-full" : "distribute", partition);
509 		} else {
510 			printf("Error: unknown preloaded partition '%s'\n", partition);
511 			return AVB_IO_RESULT_ERROR_OOM;
512 		}
513 
514 		/*
515 		 * Already preloaded during boot/recovery loading,
516 		 * here we just return a dummy buffer.
517 		 */
518 		if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9) ||
519 		    !strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11) ||
520 		    !strncmp(partition, ANDROID_PARTITION_RESOURCE, 8)) {
521 			*out_pointer = (u8 *)avb_malloc(ARCH_DMA_MINALIGN);
522 			*out_num_bytes_preloaded = num_bytes; /* return what it expects */
523 			return AVB_IO_RESULT_OK;
524 		}
525 
526 		/* If already full preloaded, there is nothing to do and just return */
527 		if (full_preload)
528 			return AVB_IO_RESULT_OK;
529 
530 		/*
531 		 * only boot/recovery partition can reach here
532 		 * and init/vendor_boot are loaded at this round.
533 		 */
534 		load_addr = env_get_ulong("kernel_addr_r", 16, 0);
535 		if (!load_addr)
536 			return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
537 
538 		ret = android_image_load_by_partname(dev_desc, partition, &load_addr);
539 		if (!ret) {
540 			*out_pointer = (u8 *)load_addr;
541 			*out_num_bytes_preloaded = num_bytes; /* return what it expects */
542 			ret = AVB_IO_RESULT_OK;
543 		} else {
544 			ret = AVB_IO_RESULT_ERROR_IO;
545 		}
546 	}
547 
548 	return ret;
549 }
550 #endif
551 
validate_public_key_for_partition(AvbOps * ops,const char * partition,const uint8_t * public_key_data,size_t public_key_length,const uint8_t * public_key_metadata,size_t public_key_metadata_length,bool * out_is_trusted,uint32_t * out_rollback_index_location)552 AvbIOResult validate_public_key_for_partition(AvbOps *ops,
553 					      const char *partition,
554 					      const uint8_t *public_key_data,
555 					      size_t public_key_length,
556 					      const uint8_t *public_key_metadata,
557 					      size_t public_key_metadata_length,
558 					      bool *out_is_trusted,
559 					      uint32_t *out_rollback_index_location)
560 {
561 /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */
562 #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \
563     defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE)
564 	if (out_is_trusted) {
565 		avb_atx_validate_vbmeta_public_key(ops,
566 						   public_key_data,
567 						   public_key_length,
568 						   public_key_metadata,
569 						   public_key_metadata_length,
570 						   out_is_trusted);
571 	}
572 #else
573 	if (out_is_trusted)
574 		*out_is_trusted = true;
575 #endif
576 	*out_rollback_index_location = 0;
577 	return AVB_IO_RESULT_OK;
578 }
579 
avb_ops_user_new(void)580 AvbOps *avb_ops_user_new(void)
581 {
582 	AvbOps *ops = NULL;
583 	struct AvbOpsData *ops_data = NULL;
584 
585 	ops = calloc(1, sizeof(AvbOps));
586 	if (!ops) {
587 		printf("Error allocating memory for AvbOps.\n");
588 		goto out;
589 	}
590 	ops->ab_ops = calloc(1, sizeof(AvbABOps));
591 	if (!ops->ab_ops) {
592 		printf("Error allocating memory for AvbABOps.\n");
593 		free(ops);
594 		goto out;
595 	}
596 
597 	ops->atx_ops = calloc(1, sizeof(AvbAtxOps));
598 	if (!ops->atx_ops) {
599 		printf("Error allocating memory for AvbAtxOps.\n");
600 		free(ops->ab_ops);
601 		free(ops);
602 		goto out;
603 	}
604 
605 	ops_data = calloc(1, sizeof(struct AvbOpsData));
606 	if (!ops_data) {
607 		printf("Error allocating memory for AvbOpsData.\n");
608 		free(ops->atx_ops);
609 		free(ops->ab_ops);
610 		free(ops);
611 		goto out;
612 	}
613 
614 	ops->ab_ops->ops = ops;
615 	ops->atx_ops->ops = ops;
616 	ops_data->ops = ops;
617 	ops->user_data = ops_data;
618 
619 	ops->read_from_partition = read_from_partition;
620 	ops->write_to_partition = write_to_partition;
621 	ops->validate_vbmeta_public_key = validate_vbmeta_public_key;
622 	ops->read_rollback_index = read_rollback_index;
623 	ops->write_rollback_index = write_rollback_index;
624 	ops->read_is_device_unlocked = read_is_device_unlocked;
625 	ops->write_is_device_unlocked = write_is_device_unlocked;
626 	ops->get_unique_guid_for_partition = get_unique_guid_for_partition;
627 	ops->get_size_of_partition = get_size_of_partition;
628 #ifdef CONFIG_ANDROID_BOOT_IMAGE
629 	ops->get_preloaded_partition = get_preloaded_partition;
630 #endif
631 	ops->validate_public_key_for_partition = validate_public_key_for_partition;
632 	ops->ab_ops->read_ab_metadata = avb_ab_data_read;
633 	ops->ab_ops->write_ab_metadata = avb_ab_data_write;
634 	ops->atx_ops->read_permanent_attributes = avb_read_perm_attr;
635 	ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash;
636 	ops->atx_ops->set_key_version = avb_set_key_version;
637 	ops->atx_ops->get_random = rk_get_random;
638 
639 	return ops;
640 out:
641 	return NULL;
642 }
643 
avb_ops_user_free(AvbOps * ops)644 void avb_ops_user_free(AvbOps *ops)
645 {
646 	free(ops->user_data);
647 	free(ops->ab_ops);
648 	free(ops->atx_ops);
649 	free(ops);
650 }
651