xref: /rk3399_rockchip-uboot/lib/avb/rk_avb_user/rk_avb_ops_user.c (revision 1490eb89f4697b02cfb8f826d2f5eaf37edcbd47)
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 #ifndef CONFIG_ANDROID_AVB
158 		printf("###There is no bootable slot, bring up last_boot!###\n");
159 		if (rk_get_lastboot() == 1)
160 			memcpy(select_slot, "_b", 2);
161 		else if(rk_get_lastboot() == 0)
162 			memcpy(select_slot, "_a", 2);
163 		else
164 #endif
165 			return -1;
166 		ret = 0;
167 	}
168 
169 	avb_ops_user_free(ops);
170 	return ret;
171 }
172 
173 int rk_avb_read_permanent_attributes(uint8_t *attributes, uint32_t size)
174 {
175 #ifdef CONFIG_OPTEE_CLIENT
176 	if(trusty_read_permanent_attributes(attributes, size) != 0) {
177 		printf("trusty_read_permanent_attributes failed!\n");
178 		return -1;
179 	}
180 
181 	return 0;
182 #else
183 	return -1;
184 #endif
185 }
186 
187 int rk_avb_write_permanent_attributes(uint8_t *attributes, uint32_t size)
188 {
189 #ifdef CONFIG_OPTEE_CLIENT
190 	if(trusty_write_permanent_attributes(attributes, size) != 0) {
191 		printf("trusty_write_permanent_attributes failed!\n");
192 		return -1;
193 	}
194 
195 	return 0;
196 #else
197 	return -1;
198 #endif
199 }
200 
201 int rk_avb_read_flash_lock_state(uint8_t *flash_lock_state)
202 {
203 #ifdef CONFIG_OPTEE_CLIENT
204 	int ret;
205 
206 	ret = trusty_read_flash_lock_state(flash_lock_state);
207 	switch (ret) {
208 	case TEE_SUCCESS:
209 		break;
210 	case TEE_ERROR_GENERIC:
211 	case TEE_ERROR_NO_DATA:
212 	case TEE_ERROR_ITEM_NOT_FOUND:
213 		*flash_lock_state = 1;
214 		if (trusty_write_flash_lock_state(*flash_lock_state)) {
215 			avb_error("trusty_write_flash_lock_state error!");
216 			ret = -1;
217 		} else {
218 			ret = trusty_read_flash_lock_state(flash_lock_state);
219 		}
220 		break;
221 	default:
222 		printf("%s: trusty_read_flash_lock_state failed\n", __FILE__);
223 	}
224 
225 	return ret;
226 #else
227 	return -1;
228 #endif
229 }
230 
231 int rk_avb_write_flash_lock_state(uint8_t flash_lock_state)
232 {
233 #ifdef CONFIG_OPTEE_CLIENT
234 	if (trusty_write_flash_lock_state(flash_lock_state)) {
235 		printf("trusty_write_flash_lock_state error!\n");
236 		return -1;
237 	}
238 
239 	return 0;
240 #else
241 	return -1;
242 #endif
243 }
244 
245 int rk_avb_write_lock_state(uint8_t lock_state)
246 {
247 #ifdef CONFIG_OPTEE_CLIENT
248 	if (trusty_write_lock_state(lock_state)) {
249 		printf("trusty_write_lock_state error!\n");
250 		return -1;
251 	}
252 
253 	return 0;
254 #else
255 	return -1;
256 #endif
257 }
258 
259 int rk_avb_read_lock_state(uint8_t *lock_state)
260 {
261 #ifdef CONFIG_OPTEE_CLIENT
262 	int ret;
263 
264 	ret = trusty_read_lock_state(lock_state);
265 	switch (ret) {
266 	case TEE_SUCCESS:
267 		break;
268 	case TEE_ERROR_GENERIC:
269 	case TEE_ERROR_NO_DATA:
270 	case TEE_ERROR_ITEM_NOT_FOUND:
271 		*lock_state = 1;
272 		if (rk_avb_write_lock_state(*lock_state)) {
273 			avb_error("avb_write_lock_state error!");
274 			ret = -1;
275 		} else {
276 			ret = trusty_read_lock_state(lock_state);
277 		}
278 		break;
279 	default:
280 		printf("%s: trusty_read_lock_state failed\n", __FILE__);
281 	}
282 
283 	return ret;
284 #else
285 	return -1;
286 #endif
287 }
288 
289 int rk_avb_write_perm_attr_flag(uint8_t flag)
290 {
291 #ifdef CONFIG_OPTEE_CLIENT
292 	if (trusty_write_permanent_attributes_flag(flag)) {
293 		printf("trusty_write_permanent_attributes_flag error!\n");
294 		return -1;
295 	}
296 
297 	return 0;
298 #else
299 	return -1;
300 #endif
301 }
302 
303 int rk_avb_read_perm_attr_flag(uint8_t *flag)
304 {
305 #ifdef CONFIG_OPTEE_CLIENT
306 	int ret;
307 
308 	ret = trusty_read_permanent_attributes_flag(flag);
309 	switch (ret) {
310 	case TEE_SUCCESS:
311 		break;
312 	case TEE_ERROR_GENERIC:
313 	case TEE_ERROR_NO_DATA:
314 	case TEE_ERROR_ITEM_NOT_FOUND:
315 		*flag = 0;
316 		if (rk_avb_write_perm_attr_flag(*flag)) {
317 			avb_error("avb_write_perm_attr_flag error!");
318 			ret = -1;
319 		} else {
320 			ret = trusty_read_permanent_attributes_flag(flag);
321 		}
322 		break;
323 	default:
324 		printf("%s: trusty_read_permanent_attributes_flag failed",
325 		       __FILE__);
326 	}
327 
328 	return ret;
329 #else
330 	return -1;
331 #endif
332 }
333 
334 int rk_avb_read_vbootkey_hash(uint8_t *buf, uint8_t length)
335 {
336 #ifdef CONFIG_OPTEE_CLIENT
337 	if (trusty_read_vbootkey_hash((uint32_t *)buf,
338 				      (uint32_t)length / sizeof(uint32_t))) {
339 		printf("trusty_read_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_write_vbootkey_hash(uint8_t *buf, uint8_t length)
350 {
351 #ifdef CONFIG_OPTEE_CLIENT
352 	if (trusty_write_vbootkey_hash((uint32_t *)buf,
353 				       (uint32_t)length / sizeof(uint32_t))) {
354 		printf("trusty_write_vbootkey_hash error!\n");
355 		return -1;
356 	}
357 
358 	return 0;
359 #else
360 	return -1;
361 #endif
362 }
363 
364 int rk_avb_close_optee_client(void)
365 {
366 #ifdef CONFIG_OPTEE_CLIENT
367 	if(trusty_notify_optee_uboot_end()) {
368 		printf("trusty_notify_optee_uboot_end error!\n");
369 		return -1;
370 	}
371 
372 	return 0;
373 #else
374 	return -1;
375 #endif
376 }
377 
378 int rk_avb_read_attribute_hash(uint8_t *buf, uint8_t length)
379 {
380 #ifdef CONFIG_OPTEE_CLIENT
381 	if (trusty_read_attribute_hash((uint32_t *)buf,
382 	    (uint32_t)(length/sizeof(uint32_t)))) {
383 		printf("trusty_read_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_write_attribute_hash(uint8_t *buf, uint8_t length)
394 {
395 #ifdef CONFIG_OPTEE_CLIENT
396 	if (trusty_write_attribute_hash((uint32_t *)buf,
397 	    (uint32_t)(length/sizeof(uint32_t)))) {
398 		printf("trusty_write_attribute_hash error!\n");
399 		return -1;
400 	}
401 
402 	return 0;
403 #else
404 	return -1;
405 #endif
406 }
407 
408 int rk_avb_read_all_rollback_index(char *buffer)
409 {
410 	AvbOps* ops;
411 	uint64_t stored_rollback_index = 0;
412 	AvbIOResult io_ret;
413 	char temp[ROLLBACK_MAX_SIZE] = {0};
414 	int n;
415 
416 	ops = avb_ops_user_new();
417 	if (ops == NULL) {
418 		printf("avb_ops_user_new() failed!\n");
419 		return -1;
420 	}
421 
422 	for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
423 		io_ret = ops->read_rollback_index(
424 			ops, n, &stored_rollback_index);
425 		if (io_ret != AVB_IO_RESULT_OK)
426 			goto out;
427 		snprintf(temp, sizeof(int) + 1, "%d", n);
428 		strncat(buffer, temp, ROLLBACK_MAX_SIZE);
429 		strncat(buffer, ":", 1);
430 		snprintf(temp, sizeof(uint64_t) + 1, "%lld",
431 			 stored_rollback_index);
432 		strncat(buffer, temp, ROLLBACK_MAX_SIZE);
433 		strncat(buffer, ",", 1);
434 	}
435 
436 	io_ret =
437 		ops->read_rollback_index(ops,
438 					 AVB_ATX_PIK_VERSION_LOCATION,
439 					 &stored_rollback_index);
440 	if (io_ret != AVB_IO_RESULT_OK) {
441 		avb_error("Failed to read PIK minimum version.\n");
442 		goto out;
443 	}
444 	/* PIK rollback index */
445 	snprintf(temp, sizeof(int) + 1, "%d", AVB_ATX_PIK_VERSION_LOCATION);
446 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
447 	strncat(buffer, ":", 1);
448 	snprintf(temp, sizeof(uint64_t) + 1, "%lld", stored_rollback_index);
449 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
450 	strncat(buffer, ",", 1);
451 	io_ret = ops->read_rollback_index(ops,
452 					  AVB_ATX_PSK_VERSION_LOCATION,
453 					  &stored_rollback_index);
454 	if (io_ret != AVB_IO_RESULT_OK) {
455 		avb_error("Failed to read PSK minimum version.\n");
456 		goto out;
457 	}
458 	/* PSK rollback index */
459 	snprintf(temp, sizeof(int) + 1, "%d", AVB_ATX_PSK_VERSION_LOCATION);
460 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
461 	strncat(buffer, ":", 1);
462 	snprintf(temp, sizeof(uint64_t) + 1, "%lld", stored_rollback_index);
463 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
464 	debug("%s\n", buffer);
465 	avb_ops_user_free(ops);
466 
467 	return 0;
468 out:
469 	avb_ops_user_free(ops);
470 
471 	return -1;
472 }
473 
474 int rk_avb_read_bootloader_locked_flag(uint8_t *flag)
475 {
476 #ifdef CONFIG_OPTEE_CLIENT
477 	if (trusty_read_vbootkey_enable_flag(flag)) {
478 		return -1;
479 	}
480 	return 0;
481 #else
482 	return -1;
483 #endif
484 }
485 
486 #ifdef CONFIG_SUPPORT_EMMC_RPMB
487 static int curr_device = -1;
488 
489 int rk_bootloader_rollback_index_read(uint32_t offset, uint32_t bytes,
490 				      void *rb_index)
491 {
492 
493 	struct mmc *mmc;
494 	uint8_t rpmb_buf[256] = {0};
495 	uint32_t n;
496 	char original_part;
497 
498 	if ((offset + bytes) > 256)
499 		return -1;
500 
501 	if (curr_device < 0) {
502 		if (get_mmc_num() > 0)
503 			curr_device = 0;
504 		else {
505 			avb_error("No MMC device available");
506 			return -1;
507 		}
508 	}
509 
510 	mmc = find_mmc_device(curr_device);
511 	/* Switch to the RPMB partition */
512 #ifndef CONFIG_BLK
513 	original_part = mmc->block_dev.hwpart;
514 #else
515 	original_part = mmc_get_blk_desc(mmc)->hwpart;
516 #endif
517 	if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) !=
518 	    0)
519 		return -1;
520 
521 	n =  mmc_rpmb_read(mmc, rpmb_buf, RPMB_BASE_ADDR, 1, NULL);
522 	if (n != 1)
523 		return -1;
524 
525 	/* Return to original partition */
526 	if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) !=
527 	    0)
528 		return -1;
529 
530 	memcpy(rb_index, (void*)&rpmb_buf[offset], bytes);
531 
532 	return 0;
533 }
534 
535 int rk_avb_get_bootloader_min_version(char *buffer)
536 {
537 	uint32_t rb_index;
538 	char temp[ROLLBACK_MAX_SIZE] = {0};
539 
540 	if (rk_bootloader_rollback_index_read(UBOOT_RB_INDEX_OFFSET,
541 					      sizeof(uint32_t), &rb_index)) {
542 		avb_error("Can not read uboot rollback index");
543 		return -1;
544 	}
545 	snprintf(temp, sizeof(int) + 1, "%d", 0);
546 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
547 	strncat(buffer, ":", 1);
548 	snprintf(temp, sizeof(uint32_t) + 1, "%d", rb_index);
549 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
550 	strncat(buffer, ",", 1);
551 
552 	if (rk_bootloader_rollback_index_read(TRUST_RB_INDEX_OFFSET,
553 					      sizeof(uint32_t), &rb_index)) {
554 		avb_error("Can not read trust rollback index");
555 		return -1;
556 	}
557 
558 	snprintf(temp, sizeof(int) + 1, "%d", 1);
559 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
560 	strncat(buffer, ":", 1);
561 	snprintf(temp, sizeof(uint32_t) + 1, "%d", rb_index);
562 	strncat(buffer, temp, ROLLBACK_MAX_SIZE);
563 
564 	return 0;
565 }
566 #endif
567 
568 void rk_avb_get_at_vboot_state(char *buf)
569 {
570 	char temp_flag = 0;
571 	char *lock_val = NULL;
572 	char *unlock_dis_val = NULL;
573 	char *perm_attr_flag = NULL;
574 	char *bootloader_locked_flag = NULL;
575 	char *rollback_indices;
576 	char min_versions[ROLLBACK_MAX_SIZE + 1] = {0};
577 	int n;
578 
579 	if (rk_avb_read_perm_attr_flag((uint8_t *)&temp_flag)) {
580 		avb_error("Can not read perm_attr_flag!");
581 		perm_attr_flag = "";
582 	} else {
583 		perm_attr_flag = temp_flag ? "1" : "0";
584 	}
585 
586 	temp_flag = 0;
587 	if (rk_avb_read_lock_state((uint8_t *)&temp_flag)) {
588 		avb_error("Can not read lock state!");
589 		lock_val = "";
590 		unlock_dis_val = "";
591 	} else {
592 		lock_val = (temp_flag & LOCK_MASK) ? "0" : "1";
593 		unlock_dis_val = (temp_flag & UNLOCK_DISABLE_MASK) ? "1" : "0";
594 	}
595 
596 	temp_flag = 0;
597 	if (rk_avb_read_bootloader_locked_flag((uint8_t *)&temp_flag)) {
598 		avb_error("Can not read bootloader locked flag!");
599 		bootloader_locked_flag = "";
600 	} else {
601 		bootloader_locked_flag = temp_flag ? "1" : "0";
602 	}
603 
604 	rollback_indices = malloc(VBOOT_STATE_SIZE);
605 	if (!rollback_indices) {
606 		avb_error("No buff to malloc!");
607 		return;
608 	}
609 
610 	memset(rollback_indices, 0, VBOOT_STATE_SIZE);
611 	if (rk_avb_read_all_rollback_index(rollback_indices))
612 		avb_error("Can not read avb_min_ver!");
613 
614 	/* bootloader-min-versions */
615 	if (rk_avb_get_bootloader_min_version(min_versions))
616 		avb_error("Call rk_avb_get_bootloader_min_version error!");
617 
618 	n = snprintf(buf, VBOOT_STATE_SIZE - 1,
619 		     "avb-perm-attr-set=%s\n"
620 		     "avb-locked=%s\n"
621 		     "avb-unlock-disabled=%s\n"
622 		     "bootloader-locked=%s\n"
623 		     "avb-min-versions=%s\n"
624 		     "bootloader-min-versions=%s\n",
625 		     perm_attr_flag,
626 		     lock_val,
627 		     unlock_dis_val,
628 		     bootloader_locked_flag,
629 		     rollback_indices,
630 		     min_versions);
631 	if (n >= VBOOT_STATE_SIZE) {
632 		avb_error("The VBOOT_STATE buf is truncated\n");
633 		buf[VBOOT_STATE_SIZE - 1] = 0;
634 	}
635 	debug("The vboot state buf is %s\n", buf);
636 	free(rollback_indices);
637 }
638 
639 int rk_avb_get_ab_info(AvbABData* ab_data)
640 {
641 	AvbOps* ops;
642 	AvbIOResult io_ret = AVB_IO_RESULT_OK;
643 	int ret = 0;
644 
645 	ops = avb_ops_user_new();
646 	if (ops == NULL) {
647 		printf("%s: avb_ops_user_new() failed!\n", __FILE__);
648 		return -1;
649 	}
650 
651 	io_ret = ops->ab_ops->read_ab_metadata(ops->ab_ops, ab_data);
652 	if (io_ret != AVB_IO_RESULT_OK) {
653 		avb_error("I/O error while loading A/B metadata.\n");
654 		ret = -1;
655 	}
656 
657 	avb_ops_user_free(ops);
658 
659 	return ret;
660 }
661 
662 int rk_avb_get_part_has_slot_info(const char *base_name)
663 {
664 	char *part_name;
665 	int part_num;
666 	size_t part_name_len;
667 	disk_partition_t part_info;
668 	struct blk_desc *dev_desc;
669 	const char *slot_suffix = "_a";
670 
671 	dev_desc = rockchip_get_bootdev();
672 	if (!dev_desc) {
673 		printf("%s: Could not find device!\n", __func__);
674 		return -1;
675 	}
676 
677 	if (base_name == NULL) {
678 		printf("The base_name is NULL!\n");
679 		return -1;
680 	}
681 
682 	part_name_len = strlen(base_name) + 1;
683 	part_name_len += strlen(slot_suffix);
684 	part_name = malloc(part_name_len);
685 	if (!part_name) {
686 		printf("%s can not malloc a buffer!\n", __FILE__);
687 		return -1;
688 	}
689 
690 	memset(part_name, 0, part_name_len);
691 	snprintf(part_name, part_name_len, "%s%s", base_name, slot_suffix);
692 	part_num = part_get_info_by_name(dev_desc, part_name, &part_info);
693 	if (part_num < 0) {
694 		printf("Could not find partition \"%s\"\n", part_name);
695 		part_num = -1;
696 	}
697 
698 	free(part_name);
699 	return part_num;
700 }
701 
702 int rk_auth_unlock(void *buffer, char *out_is_trusted)
703 {
704 	AvbOps* ops;
705 
706 	ops = avb_ops_user_new();
707 	if (ops == NULL) {
708 		avb_error("avb_ops_user_new() failed!");
709 		return -1;
710 	}
711 
712 	if (avb_atx_validate_unlock_credential(ops->atx_ops,
713 					   (AvbAtxUnlockCredential*)buffer,
714 					   (bool*)out_is_trusted)) {
715 		avb_ops_user_free(ops);
716 		return -1;
717 	}
718 	avb_ops_user_free(ops);
719 	if (*out_is_trusted == true)
720 		return 0;
721 	else
722 		return -1;
723 }
724 
725 int rk_generate_unlock_challenge(void *buffer, uint32_t *challenge_len)
726 {
727 	AvbOps* ops;
728 	AvbIOResult result = AVB_IO_RESULT_OK;
729 
730 	ops = avb_ops_user_new();
731 	if (ops == NULL) {
732 		avb_error("avb_ops_user_new() failed!");
733 		return -1;
734 	}
735 
736 	result = avb_atx_generate_unlock_challenge(ops->atx_ops,
737 						   (AvbAtxUnlockChallenge *)buffer);
738 	avb_ops_user_free(ops);
739 	*challenge_len = sizeof(AvbAtxUnlockChallenge);
740 	if (result == AVB_IO_RESULT_OK)
741 		return 0;
742 	else
743 		return -1;
744 }
745 
746 int rk_get_lastboot(void)
747 {
748 
749 	AvbIOResult io_ret = AVB_IO_RESULT_OK;
750 	AvbABData ab_data;
751 	int lastboot = -1;
752 	AvbOps* ops;
753 
754 	ops = avb_ops_user_new();
755 	if (ops == NULL) {
756 		printf("avb_ops_user_new() failed!\n");
757 		return -1;
758 	}
759 
760 	io_ret = ops->ab_ops->read_ab_metadata(ops->ab_ops, &ab_data);
761 	if (io_ret != AVB_IO_RESULT_OK) {
762 		avb_error("I/O error while loading A/B metadata.\n");
763 		goto out;
764 	}
765 
766 	lastboot = ab_data.last_boot;
767 out:
768 	avb_ops_user_free(ops);
769 
770 	return lastboot;
771 }
772 
773 int rk_avb_init_ab_metadata(void)
774 {
775 	AvbOps *ops;
776 	AvbABData ab_data;
777 
778 	memset(&ab_data, 0, sizeof(AvbABData));
779 	debug("sizeof(AvbABData) = %d\n", (int)(size_t)sizeof(AvbABData));
780 
781 	ops = avb_ops_user_new();
782 	if (ops == NULL) {
783 		printf("avb_ops_user_new() failed!\n");
784 		return -1;
785 	}
786 
787 	avb_ab_data_init(&ab_data);
788 	if (ops->ab_ops->write_ab_metadata(ops->ab_ops, &ab_data) != 0) {
789 		printf("do_avb_init_ab_metadata error!\n");
790 		avb_ops_user_free(ops);
791 		return -1;
792 	}
793 
794 	printf("Initialize ab data to misc partition success.\n");
795 	avb_ops_user_free(ops);
796 
797 	return 0;
798 }
799