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