xref: /rk3399_rockchip-uboot/lib/avb/rk_avb_user/rk_avb_ops_user.c (revision 28386b6dc69ba6ece0345798f08ef0aed9fb0691)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <image.h>
9 #include <android_image.h>
10 #include <malloc.h>
11 #include <mapmem.h>
12 #include <errno.h>
13 #include <command.h>
14 #include <mmc.h>
15 #include <blk.h>
16 #include <part.h>
17 #include <android_avb/avb_ops_user.h>
18 #include <android_avb/libavb_ab.h>
19 #include <android_avb/avb_atx_validate.h>
20 #include <android_avb/avb_atx_types.h>
21 #include <optee_include/OpteeClientInterface.h>
22 #include <optee_include/tee_api_defines.h>
23 #include <android_avb/avb_vbmeta_image.h>
24 #include <android_avb/avb_atx_validate.h>
25 #include <android_avb/rk_avb_ops_user.h>
26 #include <boot_rkimg.h>
27 #include <asm/arch/rk_atags.h>
28 
29 /* rk used */
30 int rk_avb_get_pub_key(struct rk_pub_key *pub_key)
31 {
32 	struct tag *t = NULL;
33 
34 	t = atags_get_tag(ATAG_PUB_KEY);
35 	if (!t)
36 		return -1;
37 
38 	memcpy(pub_key, t->u.pub_key.data, sizeof(struct rk_pub_key));
39 
40 	return 0;
41 }
42 int rk_avb_get_perm_attr_cer(uint8_t *cer, uint32_t size)
43 {
44 #ifdef CONFIG_OPTEE_CLIENT
45 	if (trusty_read_permanent_attributes_cer((uint8_t *)cer, size))
46 		return -EIO;
47 
48 	return 0;
49 #else
50 	return -1;
51 #endif
52 }
53 
54 int rk_avb_set_perm_attr_cer(uint8_t *cer, uint32_t size)
55 {
56 #ifdef CONFIG_OPTEE_CLIENT
57 	if (trusty_write_permanent_attributes_cer((uint8_t *)cer, size))
58 		return -EIO;
59 
60 	return 0;
61 #else
62 	return -1;
63 #endif
64 }
65 
66 int rk_avb_read_slot_count(char *slot_count)
67 {
68 	*slot_count = SLOT_NUM;
69 
70 	return 0;
71 }
72 
73 int rk_avb_read_slot_suffixes(char *slot_suffixes)
74 {
75 	memcpy(slot_suffixes, CURR_SYSTEM_SLOT_SUFFIX,
76 	       strlen(CURR_SYSTEM_SLOT_SUFFIX));
77 
78 	return 0;
79 }
80 
81 int rk_avb_set_slot_active(unsigned int *slot_number)
82 {
83 	AvbOps* ops;
84 	ops = avb_ops_user_new();
85 	int ret = 0;
86 
87 	if (ops == NULL) {
88 		printf("avb_ops_user_new() failed!\n");
89 		return -1;
90 	}
91 
92 	debug("set_slot_active\n");
93 	if (avb_ab_mark_slot_active(ops->ab_ops, *slot_number) != 0) {
94 		printf("set_slot_active error!\n");
95 		ret = -1;
96 	}
97 
98 	avb_ops_user_free(ops);
99 	return ret;
100 }
101 
102 static bool slot_is_bootable(AvbABSlotData* slot) {
103 	return (slot->priority > 0) &&
104 	       (slot->successful_boot || (slot->tries_remaining > 0));
105 }
106 
107 AvbABFlowResult rk_avb_ab_slot_select(AvbABOps* ab_ops,char* select_slot)
108 {
109 	AvbABFlowResult ret = AVB_AB_FLOW_RESULT_OK;
110 	AvbIOResult io_ret = AVB_IO_RESULT_OK;
111 	AvbABData ab_data;
112 	size_t slot_index_to_boot;
113 
114 	io_ret = ab_ops->read_ab_metadata(ab_ops, &ab_data);
115 	if (io_ret != AVB_IO_RESULT_OK) {
116 		avb_error("I/O error while loading A/B metadata.\n");
117 		ret = AVB_AB_FLOW_RESULT_ERROR_IO;
118 		goto out;
119 	}
120 	if (slot_is_bootable(&ab_data.slots[0]) && slot_is_bootable(&ab_data.slots[1])) {
121 		if (ab_data.slots[1].priority > ab_data.slots[0].priority) {
122 			slot_index_to_boot = 1;
123 		} else {
124 			slot_index_to_boot = 0;
125 		}
126 	} else if(slot_is_bootable(&ab_data.slots[0])) {
127 		slot_index_to_boot = 0;
128 	} else if(slot_is_bootable(&ab_data.slots[1])) {
129 		slot_index_to_boot = 1;
130 	} else {
131 		avb_error("No bootable slots found.\n");
132 		ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
133 		goto out;
134 	}
135 
136 	if (slot_index_to_boot == 0) {
137 		strcpy(select_slot, "_a");
138 	} else if(slot_index_to_boot == 1) {
139 		strcpy(select_slot, "_b");
140 	}
141 out:
142 	return ret;
143 }
144 
145 int rk_avb_get_current_slot(char *select_slot)
146 {
147 	AvbOps* ops;
148 	int ret = 0;
149 
150 	ops = avb_ops_user_new();
151 	if (ops == NULL) {
152 		printf("avb_ops_user_new() failed!\n");
153 		return -1;
154 	}
155 
156 	if (rk_avb_ab_slot_select(ops->ab_ops, select_slot) != 0) {
157 		printf("###There is no bootable slot, bring up last_boot!###\n");
158 		if (rk_get_lastboot() == 1)
159 			memcpy(select_slot, "_b", 2);
160 		else if(rk_get_lastboot() == 0)
161 			memcpy(select_slot, "_a", 2);
162 		else
163 			return -1;
164 		ret = 0;
165 	}
166 
167 	avb_ops_user_free(ops);
168 	return ret;
169 }
170 
171 int rk_avb_read_permanent_attributes(uint8_t *attributes, uint32_t size)
172 {
173 #ifdef CONFIG_OPTEE_CLIENT
174 	if(trusty_read_permanent_attributes(attributes, size) != 0) {
175 		printf("trusty_read_permanent_attributes failed!\n");
176 		return -1;
177 	}
178 
179 	return 0;
180 #else
181 	return -1;
182 #endif
183 }
184 
185 int rk_avb_write_permanent_attributes(uint8_t *attributes, uint32_t size)
186 {
187 #ifdef CONFIG_OPTEE_CLIENT
188 	if(trusty_write_permanent_attributes(attributes, size) != 0) {
189 		printf("trusty_write_permanent_attributes failed!\n");
190 		return -1;
191 	}
192 
193 	return 0;
194 #else
195 	return -1;
196 #endif
197 }
198 
199 int rk_avb_read_flash_lock_state(uint8_t *flash_lock_state)
200 {
201 #ifdef CONFIG_OPTEE_CLIENT
202 	int ret;
203 
204 	ret = trusty_read_flash_lock_state(flash_lock_state);
205 	switch (ret) {
206 	case TEE_SUCCESS:
207 		break;
208 	case TEE_ERROR_GENERIC:
209 	case TEE_ERROR_NO_DATA:
210 	case TEE_ERROR_ITEM_NOT_FOUND:
211 		*flash_lock_state = 1;
212 		if (trusty_write_flash_lock_state(*flash_lock_state)) {
213 			avb_error("trusty_write_flash_lock_state error!");
214 			ret = -1;
215 		} else {
216 			ret = trusty_read_flash_lock_state(flash_lock_state);
217 		}
218 		break;
219 	default:
220 		printf("%s: trusty_read_flash_lock_state failed\n", __FILE__);
221 	}
222 
223 	return ret;
224 #else
225 	return -1;
226 #endif
227 }
228 
229 int rk_avb_write_flash_lock_state(uint8_t flash_lock_state)
230 {
231 #ifdef CONFIG_OPTEE_CLIENT
232 	if (trusty_write_flash_lock_state(flash_lock_state)) {
233 		printf("trusty_write_flash_lock_state error!\n");
234 		return -1;
235 	}
236 
237 	return 0;
238 #else
239 	return -1;
240 #endif
241 }
242 
243 int rk_avb_write_lock_state(uint8_t lock_state)
244 {
245 #ifdef CONFIG_OPTEE_CLIENT
246 	if (trusty_write_lock_state(lock_state)) {
247 		printf("trusty_write_lock_state error!\n");
248 		return -1;
249 	}
250 
251 	return 0;
252 #else
253 	return -1;
254 #endif
255 }
256 
257 int rk_avb_read_lock_state(uint8_t *lock_state)
258 {
259 #ifdef CONFIG_OPTEE_CLIENT
260 	int ret;
261 
262 	ret = trusty_read_lock_state(lock_state);
263 	switch (ret) {
264 	case TEE_SUCCESS:
265 		break;
266 	case TEE_ERROR_GENERIC:
267 	case TEE_ERROR_NO_DATA:
268 	case TEE_ERROR_ITEM_NOT_FOUND:
269 		*lock_state = 1;
270 		if (rk_avb_write_lock_state(*lock_state)) {
271 			avb_error("avb_write_lock_state error!");
272 			ret = -1;
273 		} else {
274 			ret = trusty_read_lock_state(lock_state);
275 		}
276 		break;
277 	default:
278 		printf("%s: trusty_read_lock_state failed\n", __FILE__);
279 	}
280 
281 	return ret;
282 #else
283 	return -1;
284 #endif
285 }
286 
287 int rk_avb_write_perm_attr_flag(uint8_t flag)
288 {
289 #ifdef CONFIG_OPTEE_CLIENT
290 	if (trusty_write_permanent_attributes_flag(flag)) {
291 		printf("trusty_write_permanent_attributes_flag error!\n");
292 		return -1;
293 	}
294 
295 	return 0;
296 #else
297 	return -1;
298 #endif
299 }
300 
301 int rk_avb_read_perm_attr_flag(uint8_t *flag)
302 {
303 #ifdef CONFIG_OPTEE_CLIENT
304 	int ret;
305 
306 	ret = trusty_read_permanent_attributes_flag(flag);
307 	switch (ret) {
308 	case TEE_SUCCESS:
309 		break;
310 	case TEE_ERROR_GENERIC:
311 	case TEE_ERROR_NO_DATA:
312 	case TEE_ERROR_ITEM_NOT_FOUND:
313 		*flag = 0;
314 		if (rk_avb_write_perm_attr_flag(*flag)) {
315 			avb_error("avb_write_perm_attr_flag error!");
316 			ret = -1;
317 		} else {
318 			ret = trusty_read_permanent_attributes_flag(flag);
319 		}
320 		break;
321 	default:
322 		printf("%s: trusty_read_permanent_attributes_flag failed",
323 		       __FILE__);
324 	}
325 
326 	return ret;
327 #else
328 	return -1;
329 #endif
330 }
331 
332 int rk_avb_read_vbootkey_hash(uint8_t *buf, uint8_t length)
333 {
334 #ifdef CONFIG_OPTEE_CLIENT
335 	if (trusty_read_vbootkey_hash((uint32_t *)buf,
336 				      (uint32_t)length / sizeof(uint32_t))) {
337 		printf("trusty_read_vbootkey_hash error!\n");
338 		return -1;
339 	}
340 
341 	return 0;
342 #else
343 	return -1;
344 #endif
345 }
346 
347 int rk_avb_write_vbootkey_hash(uint8_t *buf, uint8_t length)
348 {
349 #ifdef CONFIG_OPTEE_CLIENT
350 	if (trusty_write_vbootkey_hash((uint32_t *)buf,
351 				       (uint32_t)length / sizeof(uint32_t))) {
352 		printf("trusty_write_vbootkey_hash error!\n");
353 		return -1;
354 	}
355 
356 	return 0;
357 #else
358 	return -1;
359 #endif
360 }
361 
362 int rk_avb_close_optee_client(void)
363 {
364 #ifdef CONFIG_OPTEE_CLIENT
365 	if(trusty_notify_optee_uboot_end()) {
366 		printf("trusty_notify_optee_uboot_end error!\n");
367 		return -1;
368 	}
369 
370 	return 0;
371 #else
372 	return -1;
373 #endif
374 }
375 
376 int rk_avb_read_attribute_hash(uint8_t *buf, uint8_t length)
377 {
378 #ifdef CONFIG_OPTEE_CLIENT
379 	if (trusty_read_attribute_hash((uint32_t *)buf,
380 	    (uint32_t)(length/sizeof(uint32_t)))) {
381 		printf("trusty_read_attribute_hash error!\n");
382 		return -1;
383 	}
384 
385 	return 0;
386 #else
387 	return -1;
388 #endif
389 }
390 
391 int rk_avb_write_attribute_hash(uint8_t *buf, uint8_t length)
392 {
393 #ifdef CONFIG_OPTEE_CLIENT
394 	if (trusty_write_attribute_hash((uint32_t *)buf,
395 	    (uint32_t)(length/sizeof(uint32_t)))) {
396 		printf("trusty_write_attribute_hash error!\n");
397 		return -1;
398 	}
399 
400 	return 0;
401 #else
402 	return -1;
403 #endif
404 }
405 
406 int rk_avb_read_all_rollback_index(char *buffer)
407 {
408 	AvbOps* ops;
409 	uint64_t stored_rollback_index = 0;
410 	AvbIOResult io_ret;
411 	char temp[ROLLBACK_MAX_SIZE] = {0};
412 	int n;
413 
414 	ops = avb_ops_user_new();
415 	if (ops == NULL) {
416 		printf("avb_ops_user_new() failed!\n");
417 		return -1;
418 	}
419 
420 	for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
421 		io_ret = ops->read_rollback_index(
422 			ops, n, &stored_rollback_index);
423 		if (io_ret != AVB_IO_RESULT_OK)
424 			goto out;
425 		snprintf(temp, sizeof(int) + 1, "%d", n);
426 		strncat(buffer, temp, ROLLBACK_MAX_SIZE);
427 		strncat(buffer, ":", 1);
428 		snprintf(temp, sizeof(uint64_t) + 1, "%lld",
429 			 stored_rollback_index);
430 		strncat(buffer, temp, ROLLBACK_MAX_SIZE);
431 		strncat(buffer, ",", 1);
432 	}
433 
434 	io_ret =
435 		ops->read_rollback_index(ops,
436 					 AVB_ATX_PIK_VERSION_LOCATION,
437 					 &stored_rollback_index);
438 	if (io_ret != AVB_IO_RESULT_OK) {
439 		avb_error("Failed to read PIK minimum version.\n");
440 		goto out;
441 	}
442 	/* PIK rollback index */
443 	snprintf(temp, sizeof(int) + 1, "%d", AVB_ATX_PIK_VERSION_LOCATION);
444 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
445 	strncat(buffer, ":", 1);
446 	snprintf(temp, sizeof(uint64_t) + 1, "%lld", stored_rollback_index);
447 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
448 	strncat(buffer, ",", 1);
449 	io_ret = ops->read_rollback_index(ops,
450 					  AVB_ATX_PSK_VERSION_LOCATION,
451 					  &stored_rollback_index);
452 	if (io_ret != AVB_IO_RESULT_OK) {
453 		avb_error("Failed to read PSK minimum version.\n");
454 		goto out;
455 	}
456 	/* PSK rollback index */
457 	snprintf(temp, sizeof(int) + 1, "%d", AVB_ATX_PSK_VERSION_LOCATION);
458 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
459 	strncat(buffer, ":", 1);
460 	snprintf(temp, sizeof(uint64_t) + 1, "%lld", stored_rollback_index);
461 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
462 	debug("%s\n", buffer);
463 	avb_ops_user_free(ops);
464 
465 	return 0;
466 out:
467 	avb_ops_user_free(ops);
468 
469 	return -1;
470 }
471 
472 int rk_avb_read_bootloader_locked_flag(uint8_t *flag)
473 {
474 #ifdef CONFIG_OPTEE_CLIENT
475 	if (trusty_read_vbootkey_enable_flag(flag)) {
476 		return -1;
477 	}
478 	return 0;
479 #else
480 	return -1;
481 #endif
482 }
483 
484 #ifdef CONFIG_SUPPORT_EMMC_RPMB
485 static int curr_device = -1;
486 
487 int rk_bootloader_rollback_index_read(uint32_t offset, uint32_t bytes,
488 				      void *rb_index)
489 {
490 
491 	struct mmc *mmc;
492 	uint8_t rpmb_buf[256] = {0};
493 	uint32_t n;
494 	char original_part;
495 
496 	if ((offset + bytes) > 256)
497 		return -1;
498 
499 	if (curr_device < 0) {
500 		if (get_mmc_num() > 0)
501 			curr_device = 0;
502 		else {
503 			avb_error("No MMC device available");
504 			return -1;
505 		}
506 	}
507 
508 	mmc = find_mmc_device(curr_device);
509 	/* Switch to the RPMB partition */
510 #ifndef CONFIG_BLK
511 	original_part = mmc->block_dev.hwpart;
512 #else
513 	original_part = mmc_get_blk_desc(mmc)->hwpart;
514 #endif
515 	if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) !=
516 	    0)
517 		return -1;
518 
519 	n =  mmc_rpmb_read(mmc, rpmb_buf, RPMB_BASE_ADDR, 1, NULL);
520 	if (n != 1)
521 		return -1;
522 
523 	/* Return to original partition */
524 	if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) !=
525 	    0)
526 		return -1;
527 
528 	memcpy(rb_index, (void*)&rpmb_buf[offset], bytes);
529 
530 	return 0;
531 }
532 
533 int rk_avb_get_bootloader_min_version(char *buffer)
534 {
535 	uint32_t rb_index;
536 	char temp[ROLLBACK_MAX_SIZE] = {0};
537 
538 	if (rk_bootloader_rollback_index_read(UBOOT_RB_INDEX_OFFSET,
539 					      sizeof(uint32_t), &rb_index)) {
540 		avb_error("Can not read uboot rollback index");
541 		return -1;
542 	}
543 	snprintf(temp, sizeof(int) + 1, "%d", 0);
544 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
545 	strncat(buffer, ":", 1);
546 	snprintf(temp, sizeof(uint32_t) + 1, "%d", rb_index);
547 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
548 	strncat(buffer, ",", 1);
549 
550 	if (rk_bootloader_rollback_index_read(TRUST_RB_INDEX_OFFSET,
551 					      sizeof(uint32_t), &rb_index)) {
552 		avb_error("Can not read trust rollback index");
553 		return -1;
554 	}
555 
556 	snprintf(temp, sizeof(int) + 1, "%d", 1);
557 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
558 	strncat(buffer, ":", 1);
559 	snprintf(temp, sizeof(uint32_t) + 1, "%d", rb_index);
560 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
561 
562 	return 0;
563 }
564 #endif
565 
566 void rk_avb_get_at_vboot_state(char *buf)
567 {
568 	char temp_flag = 0;
569 	char *lock_val = NULL;
570 	char *unlock_dis_val = NULL;
571 	char *perm_attr_flag = NULL;
572 	char *bootloader_locked_flag = NULL;
573 	char *rollback_indices;
574 	char min_versions[ROLLBACK_MAX_SIZE + 1] = {0};
575 	int n;
576 
577 	if (rk_avb_read_perm_attr_flag((uint8_t *)&temp_flag)) {
578 		avb_error("Can not read perm_attr_flag!");
579 		perm_attr_flag = "";
580 	} else {
581 		perm_attr_flag = temp_flag ? "1" : "0";
582 	}
583 
584 	temp_flag = 0;
585 	if (rk_avb_read_lock_state((uint8_t *)&temp_flag)) {
586 		avb_error("Can not read lock state!");
587 		lock_val = "";
588 		unlock_dis_val = "";
589 	} else {
590 		lock_val = (temp_flag & LOCK_MASK) ? "0" : "1";
591 		unlock_dis_val = (temp_flag & UNLOCK_DISABLE_MASK) ? "1" : "0";
592 	}
593 
594 	temp_flag = 0;
595 	if (rk_avb_read_bootloader_locked_flag((uint8_t *)&temp_flag)) {
596 		avb_error("Can not read bootloader locked flag!");
597 		bootloader_locked_flag = "";
598 	} else {
599 		bootloader_locked_flag = temp_flag ? "1" : "0";
600 	}
601 
602 	rollback_indices = malloc(VBOOT_STATE_SIZE);
603 	if (!rollback_indices) {
604 		avb_error("No buff to malloc!");
605 		return;
606 	}
607 
608 	memset(rollback_indices, 0, VBOOT_STATE_SIZE);
609 	if (rk_avb_read_all_rollback_index(rollback_indices))
610 		avb_error("Can not read avb_min_ver!");
611 
612 	/* bootloader-min-versions */
613 	if (rk_avb_get_bootloader_min_version(min_versions))
614 		avb_error("Call rk_avb_get_bootloader_min_version error!");
615 
616 	n = snprintf(buf, VBOOT_STATE_SIZE - 1,
617 		     "avb-perm-attr-set=%s\n"
618 		     "avb-locked=%s\n"
619 		     "avb-unlock-disabled=%s\n"
620 		     "bootloader-locked=%s\n"
621 		     "avb-min-versions=%s\n"
622 		     "bootloader-min-versions=%s\n",
623 		     perm_attr_flag,
624 		     lock_val,
625 		     unlock_dis_val,
626 		     bootloader_locked_flag,
627 		     rollback_indices,
628 		     min_versions);
629 	if (n >= VBOOT_STATE_SIZE) {
630 		avb_error("The VBOOT_STATE buf is truncated\n");
631 		buf[VBOOT_STATE_SIZE - 1] = 0;
632 	}
633 	debug("The vboot state buf is %s\n", buf);
634 	free(rollback_indices);
635 }
636 
637 int rk_avb_get_ab_info(AvbABData* ab_data)
638 {
639 	AvbOps* ops;
640 	AvbIOResult io_ret = AVB_IO_RESULT_OK;
641 	int ret = 0;
642 
643 	ops = avb_ops_user_new();
644 	if (ops == NULL) {
645 		printf("%s: avb_ops_user_new() failed!\n", __FILE__);
646 		return -1;
647 	}
648 
649 	io_ret = ops->ab_ops->read_ab_metadata(ops->ab_ops, ab_data);
650 	if (io_ret != AVB_IO_RESULT_OK) {
651 		avb_error("I/O error while loading A/B metadata.\n");
652 		ret = -1;
653 	}
654 
655 	avb_ops_user_free(ops);
656 
657 	return ret;
658 }
659 
660 int rk_avb_get_part_has_slot_info(const char *base_name)
661 {
662 	char *part_name;
663 	int part_num;
664 	size_t part_name_len;
665 	disk_partition_t part_info;
666 	struct blk_desc *dev_desc;
667 	const char *slot_suffix = "_a";
668 
669 	dev_desc = rockchip_get_bootdev();
670 	if (!dev_desc) {
671 		printf("%s: Could not find device!\n", __func__);
672 		return -1;
673 	}
674 
675 	if (base_name == NULL) {
676 		printf("The base_name is NULL!\n");
677 		return -1;
678 	}
679 
680 	part_name_len = strlen(base_name) + 1;
681 	part_name_len += strlen(slot_suffix);
682 	part_name = malloc(part_name_len);
683 	if (!part_name) {
684 		printf("%s can not malloc a buffer!\n", __FILE__);
685 		return -1;
686 	}
687 
688 	memset(part_name, 0, part_name_len);
689 	snprintf(part_name, part_name_len, "%s%s", base_name, slot_suffix);
690 	part_num = part_get_info_by_name(dev_desc, part_name, &part_info);
691 	if (part_num < 0) {
692 		printf("Could not find partition \"%s\"\n", part_name);
693 		part_num = -1;
694 	}
695 
696 	free(part_name);
697 	return part_num;
698 }
699 
700 int rk_auth_unlock(void *buffer, char *out_is_trusted)
701 {
702 	AvbOps* ops;
703 
704 	ops = avb_ops_user_new();
705 	if (ops == NULL) {
706 		avb_error("avb_ops_user_new() failed!");
707 		return -1;
708 	}
709 
710 	if (avb_atx_validate_unlock_credential(ops->atx_ops,
711 					   (AvbAtxUnlockCredential*)buffer,
712 					   (bool*)out_is_trusted)) {
713 		avb_ops_user_free(ops);
714 		return -1;
715 	}
716 	avb_ops_user_free(ops);
717 	if (*out_is_trusted == true)
718 		return 0;
719 	else
720 		return -1;
721 }
722 
723 int rk_generate_unlock_challenge(void *buffer, uint32_t *challenge_len)
724 {
725 	AvbOps* ops;
726 	AvbIOResult result = AVB_IO_RESULT_OK;
727 
728 	ops = avb_ops_user_new();
729 	if (ops == NULL) {
730 		avb_error("avb_ops_user_new() failed!");
731 		return -1;
732 	}
733 
734 	result = avb_atx_generate_unlock_challenge(ops->atx_ops,
735 						   (AvbAtxUnlockChallenge *)buffer);
736 	avb_ops_user_free(ops);
737 	*challenge_len = sizeof(AvbAtxUnlockChallenge);
738 	if (result == AVB_IO_RESULT_OK)
739 		return 0;
740 	else
741 		return -1;
742 }
743 
744 int rk_get_lastboot(void)
745 {
746 
747 	AvbIOResult io_ret = AVB_IO_RESULT_OK;
748 	AvbABData ab_data;
749 	int lastboot = -1;
750 	AvbOps* ops;
751 
752 	ops = avb_ops_user_new();
753 	if (ops == NULL) {
754 		printf("avb_ops_user_new() failed!\n");
755 		return -1;
756 	}
757 
758 	io_ret = ops->ab_ops->read_ab_metadata(ops->ab_ops, &ab_data);
759 	if (io_ret != AVB_IO_RESULT_OK) {
760 		avb_error("I/O error while loading A/B metadata.\n");
761 		goto out;
762 	}
763 
764 	lastboot = ab_data.last_boot;
765 out:
766 	avb_ops_user_free(ops);
767 
768 	return lastboot;
769 }
770 
771 int rk_avb_init_ab_metadata(void)
772 {
773 	AvbOps *ops;
774 	AvbABData ab_data;
775 
776 	memset(&ab_data, 0, sizeof(AvbABData));
777 	debug("sizeof(AvbABData) = %d\n", (int)(size_t)sizeof(AvbABData));
778 
779 	ops = avb_ops_user_new();
780 	if (ops == NULL) {
781 		printf("avb_ops_user_new() failed!\n");
782 		return -1;
783 	}
784 
785 	avb_ab_data_init(&ab_data);
786 	if (ops->ab_ops->write_ab_metadata(ops->ab_ops, &ab_data) != 0) {
787 		printf("do_avb_init_ab_metadata error!\n");
788 		avb_ops_user_free(ops);
789 		return -1;
790 	}
791 
792 	printf("Initialize ab data to misc partition success.\n");
793 	avb_ops_user_free(ops);
794 
795 	return 0;
796 }