.. | .. |
---|
81 | 81 | return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; |
---|
82 | 82 | } |
---|
83 | 83 | |
---|
84 | | - if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { |
---|
85 | | - printf("Could not find \"%s\" partition\n", partition); |
---|
| 84 | + if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) |
---|
86 | 85 | return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; |
---|
87 | | - } |
---|
| 86 | + |
---|
88 | 87 | *out_size_in_bytes = (part_info.size) * 512; |
---|
89 | 88 | return AVB_IO_RESULT_OK; |
---|
90 | 89 | } |
---|
.. | .. |
---|
281 | 280 | { |
---|
282 | 281 | if (out_is_unlocked) { |
---|
283 | 282 | #ifdef CONFIG_OPTEE_CLIENT |
---|
| 283 | + uint8_t vboot_flag = 0; |
---|
284 | 284 | int ret; |
---|
285 | 285 | |
---|
286 | 286 | ret = trusty_read_lock_state((uint8_t *)out_is_unlocked); |
---|
.. | .. |
---|
291 | 291 | case TEE_ERROR_GENERIC: |
---|
292 | 292 | case TEE_ERROR_NO_DATA: |
---|
293 | 293 | case TEE_ERROR_ITEM_NOT_FOUND: |
---|
294 | | - *out_is_unlocked = 1; |
---|
| 294 | + if (trusty_read_vbootkey_enable_flag(&vboot_flag)) { |
---|
| 295 | + printf("Can't read vboot flag\n"); |
---|
| 296 | + return AVB_IO_RESULT_ERROR_IO; |
---|
| 297 | + } |
---|
| 298 | + |
---|
| 299 | + if (vboot_flag) |
---|
| 300 | + *out_is_unlocked = 0; |
---|
| 301 | + else |
---|
| 302 | + *out_is_unlocked = 1; |
---|
| 303 | + |
---|
295 | 304 | if (trusty_write_lock_state(*out_is_unlocked)) { |
---|
296 | 305 | printf("%s: init lock state error\n", __FILE__); |
---|
297 | 306 | ret = AVB_IO_RESULT_ERROR_IO; |
---|
.. | .. |
---|
429 | 438 | size_t* out_num_bytes_preloaded, |
---|
430 | 439 | int allow_verification_error) |
---|
431 | 440 | { |
---|
| 441 | + struct preloaded_partition *preload_info = NULL; |
---|
| 442 | + struct AvbOpsData *data = ops->user_data; |
---|
432 | 443 | struct blk_desc *dev_desc; |
---|
| 444 | + disk_partition_t part_info; |
---|
433 | 445 | ulong load_addr; |
---|
434 | | - int ret; |
---|
| 446 | + AvbIOResult ret; |
---|
| 447 | + int full_preload = 0; |
---|
435 | 448 | |
---|
436 | | - /* no need go further */ |
---|
437 | | - if (!allow_verification_error) |
---|
438 | | - return AVB_IO_RESULT_OK; |
---|
439 | | - |
---|
440 | | - printf("get image from preloaded partition...\n"); |
---|
441 | 449 | dev_desc = rockchip_get_bootdev(); |
---|
442 | 450 | if (!dev_desc) |
---|
443 | | - return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; |
---|
| 451 | + return AVB_IO_RESULT_ERROR_IO; |
---|
444 | 452 | |
---|
445 | | - load_addr = env_get_ulong("kernel_addr_r", 16, 0); |
---|
446 | | - if (!load_addr) |
---|
447 | | - return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; |
---|
| 453 | + if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { |
---|
| 454 | + printf("Could not find \"%s\" partition\n", partition); |
---|
| 455 | + return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; |
---|
| 456 | + } |
---|
448 | 457 | |
---|
449 | | - ret = android_image_load_by_partname(dev_desc, partition, &load_addr); |
---|
450 | | - if (!ret) { |
---|
451 | | - *out_pointer = (u8 *)load_addr; |
---|
452 | | - *out_num_bytes_preloaded = num_bytes; /* return what it expects */ |
---|
| 458 | + if (!allow_verification_error) { |
---|
| 459 | + if (!strncmp(partition, ANDROID_PARTITION_BOOT, 4) || |
---|
| 460 | + !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8)) |
---|
| 461 | + preload_info = &data->boot; |
---|
| 462 | + else if (!strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11)) |
---|
| 463 | + preload_info = &data->vendor_boot; |
---|
| 464 | + else if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9)) |
---|
| 465 | + preload_info = &data->init_boot; |
---|
| 466 | + else if (!strncmp(partition, ANDROID_PARTITION_RESOURCE, 8)) |
---|
| 467 | + preload_info = &data->resource; |
---|
| 468 | + |
---|
| 469 | + if (!preload_info) { |
---|
| 470 | + printf("Error: unknown full load partition '%s'\n", partition); |
---|
| 471 | + return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; |
---|
| 472 | + } |
---|
| 473 | + |
---|
| 474 | + printf("preloaded(s): %sfull image from '%s' at 0x%08lx - 0x%08lx\n", |
---|
| 475 | + preload_info->size ? "pre-" : "", partition, |
---|
| 476 | + (ulong)preload_info->addr, |
---|
| 477 | + (ulong)preload_info->addr + num_bytes); |
---|
| 478 | + |
---|
| 479 | + /* If the partition hasn't yet been preloaded, do it now.*/ |
---|
| 480 | + if (preload_info->size == 0) { |
---|
| 481 | + ret = ops->read_from_partition(ops, partition, |
---|
| 482 | + 0, num_bytes, |
---|
| 483 | + preload_info->addr, |
---|
| 484 | + &preload_info->size); |
---|
| 485 | + if (ret != AVB_IO_RESULT_OK) |
---|
| 486 | + return ret; |
---|
| 487 | + } |
---|
| 488 | + *out_pointer = preload_info->addr; |
---|
| 489 | + *out_num_bytes_preloaded = preload_info->size; |
---|
453 | 490 | ret = AVB_IO_RESULT_OK; |
---|
454 | 491 | } else { |
---|
455 | | - ret = AVB_IO_RESULT_ERROR_IO; |
---|
| 492 | + if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9) || |
---|
| 493 | + !strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11) || |
---|
| 494 | + !strncmp(partition, ANDROID_PARTITION_BOOT, 4) || |
---|
| 495 | + !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8) || |
---|
| 496 | + !strncmp(partition, ANDROID_PARTITION_RESOURCE, 8)) { |
---|
| 497 | + /* If already full preloaded, just use it */ |
---|
| 498 | + if (!strncmp(partition, ANDROID_PARTITION_BOOT, 4) || |
---|
| 499 | + !strncmp(partition, ANDROID_PARTITION_RECOVERY, 8)) { |
---|
| 500 | + preload_info = &data->boot; |
---|
| 501 | + if (preload_info->size) { |
---|
| 502 | + *out_pointer = preload_info->addr; |
---|
| 503 | + *out_num_bytes_preloaded = num_bytes; |
---|
| 504 | + full_preload = 1; |
---|
| 505 | + } |
---|
| 506 | + } |
---|
| 507 | + printf("preloaded: %s image from '%s\n", |
---|
| 508 | + full_preload ? "pre-full" : "distribute", partition); |
---|
| 509 | + } else { |
---|
| 510 | + printf("Error: unknown preloaded partition '%s'\n", partition); |
---|
| 511 | + return AVB_IO_RESULT_ERROR_OOM; |
---|
| 512 | + } |
---|
| 513 | + |
---|
| 514 | + /* |
---|
| 515 | + * Already preloaded during boot/recovery loading, |
---|
| 516 | + * here we just return a dummy buffer. |
---|
| 517 | + */ |
---|
| 518 | + if (!strncmp(partition, ANDROID_PARTITION_INIT_BOOT, 9) || |
---|
| 519 | + !strncmp(partition, ANDROID_PARTITION_VENDOR_BOOT, 11) || |
---|
| 520 | + !strncmp(partition, ANDROID_PARTITION_RESOURCE, 8)) { |
---|
| 521 | + *out_pointer = (u8 *)avb_malloc(ARCH_DMA_MINALIGN); |
---|
| 522 | + *out_num_bytes_preloaded = num_bytes; /* return what it expects */ |
---|
| 523 | + return AVB_IO_RESULT_OK; |
---|
| 524 | + } |
---|
| 525 | + |
---|
| 526 | + /* If already full preloaded, there is nothing to do and just return */ |
---|
| 527 | + if (full_preload) |
---|
| 528 | + return AVB_IO_RESULT_OK; |
---|
| 529 | + |
---|
| 530 | + /* |
---|
| 531 | + * only boot/recovery partition can reach here |
---|
| 532 | + * and init/vendor_boot are loaded at this round. |
---|
| 533 | + */ |
---|
| 534 | + load_addr = env_get_ulong("kernel_addr_r", 16, 0); |
---|
| 535 | + if (!load_addr) |
---|
| 536 | + return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; |
---|
| 537 | + |
---|
| 538 | + ret = android_image_load_by_partname(dev_desc, partition, &load_addr); |
---|
| 539 | + if (!ret) { |
---|
| 540 | + *out_pointer = (u8 *)load_addr; |
---|
| 541 | + *out_num_bytes_preloaded = num_bytes; /* return what it expects */ |
---|
| 542 | + ret = AVB_IO_RESULT_OK; |
---|
| 543 | + } else { |
---|
| 544 | + ret = AVB_IO_RESULT_ERROR_IO; |
---|
| 545 | + } |
---|
456 | 546 | } |
---|
457 | 547 | |
---|
458 | 548 | return ret; |
---|
.. | .. |
---|
489 | 579 | |
---|
490 | 580 | AvbOps *avb_ops_user_new(void) |
---|
491 | 581 | { |
---|
492 | | - AvbOps *ops; |
---|
| 582 | + AvbOps *ops = NULL; |
---|
| 583 | + struct AvbOpsData *ops_data = NULL; |
---|
493 | 584 | |
---|
494 | 585 | ops = calloc(1, sizeof(AvbOps)); |
---|
495 | 586 | if (!ops) { |
---|
.. | .. |
---|
510 | 601 | free(ops); |
---|
511 | 602 | goto out; |
---|
512 | 603 | } |
---|
| 604 | + |
---|
| 605 | + ops_data = calloc(1, sizeof(struct AvbOpsData)); |
---|
| 606 | + if (!ops_data) { |
---|
| 607 | + printf("Error allocating memory for AvbOpsData.\n"); |
---|
| 608 | + free(ops->atx_ops); |
---|
| 609 | + free(ops->ab_ops); |
---|
| 610 | + free(ops); |
---|
| 611 | + goto out; |
---|
| 612 | + } |
---|
| 613 | + |
---|
513 | 614 | ops->ab_ops->ops = ops; |
---|
514 | 615 | ops->atx_ops->ops = ops; |
---|
| 616 | + ops_data->ops = ops; |
---|
| 617 | + ops->user_data = ops_data; |
---|
515 | 618 | |
---|
516 | 619 | ops->read_from_partition = read_from_partition; |
---|
517 | 620 | ops->write_to_partition = write_to_partition; |
---|
.. | .. |
---|
533 | 636 | ops->atx_ops->set_key_version = avb_set_key_version; |
---|
534 | 637 | ops->atx_ops->get_random = rk_get_random; |
---|
535 | 638 | |
---|
536 | | -out: |
---|
537 | 639 | return ops; |
---|
| 640 | +out: |
---|
| 641 | + return NULL; |
---|
538 | 642 | } |
---|
539 | 643 | |
---|
540 | 644 | void avb_ops_user_free(AvbOps *ops) |
---|
541 | 645 | { |
---|
| 646 | + free(ops->user_data); |
---|
542 | 647 | free(ops->ab_ops); |
---|
543 | 648 | free(ops->atx_ops); |
---|
544 | 649 | free(ops); |
---|