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