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