137a7bc39SJason Zhu /* 237a7bc39SJason Zhu * Copyright (C) 2017 The Android Open Source Project 337a7bc39SJason Zhu * 437a7bc39SJason Zhu * Permission is hereby granted, free of charge, to any person 537a7bc39SJason Zhu * obtaining a copy of this software and associated documentation 637a7bc39SJason Zhu * files (the "Software"), to deal in the Software without 737a7bc39SJason Zhu * restriction, including without limitation the rights to use, copy, 837a7bc39SJason Zhu * modify, merge, publish, distribute, sublicense, and/or sell copies 937a7bc39SJason Zhu * of the Software, and to permit persons to whom the Software is 1037a7bc39SJason Zhu * furnished to do so, subject to the following conditions: 1137a7bc39SJason Zhu * 1237a7bc39SJason Zhu * The above copyright notice and this permission notice shall be 1337a7bc39SJason Zhu * included in all copies or substantial portions of the Software. 1437a7bc39SJason Zhu * 1537a7bc39SJason Zhu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1637a7bc39SJason Zhu * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1737a7bc39SJason Zhu * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1837a7bc39SJason Zhu * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 1937a7bc39SJason Zhu * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2037a7bc39SJason Zhu * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2137a7bc39SJason Zhu * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2237a7bc39SJason Zhu * SOFTWARE. 2337a7bc39SJason Zhu */ 2437a7bc39SJason Zhu 2537a7bc39SJason Zhu #include <common.h> 2637a7bc39SJason Zhu #include <image.h> 2737a7bc39SJason Zhu #include <android_image.h> 2837a7bc39SJason Zhu #include <malloc.h> 2937a7bc39SJason Zhu #include <mapmem.h> 3037a7bc39SJason Zhu #include <errno.h> 3137a7bc39SJason Zhu #include <command.h> 3237a7bc39SJason Zhu #include <mmc.h> 3337a7bc39SJason Zhu #include <blk.h> 3437a7bc39SJason Zhu #include <part.h> 3537a7bc39SJason Zhu #include <android_avb/avb_ops_user.h> 3637a7bc39SJason Zhu #include <android_avb/libavb_ab.h> 3737a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h> 3837a7bc39SJason Zhu #include <android_avb/avb_atx_types.h> 3937a7bc39SJason Zhu #include <optee_include/OpteeClientInterface.h> 4037a7bc39SJason Zhu #include <optee_include/tee_api_defines.h> 4137a7bc39SJason Zhu #include <android_avb/avb_vbmeta_image.h> 4237a7bc39SJason Zhu #include <android_avb/avb_atx_validate.h> 43459bc933SJason Zhu #include <boot_rkimg.h> 4437a7bc39SJason Zhu 4537a7bc39SJason Zhu static void byte_to_block(int64_t *offset, 4637a7bc39SJason Zhu size_t *num_bytes, 4737a7bc39SJason Zhu lbaint_t *offset_blk, 4837a7bc39SJason Zhu lbaint_t *blkcnt) 4937a7bc39SJason Zhu { 5037a7bc39SJason Zhu *offset_blk = (lbaint_t)(*offset / 512); 5137a7bc39SJason Zhu if (*num_bytes % 512 == 0) { 527c1937d6SJason Zhu if (*offset % 512 == 0) 5337a7bc39SJason Zhu *blkcnt = (lbaint_t)(*num_bytes / 512); 547c1937d6SJason Zhu else 5537a7bc39SJason Zhu *blkcnt = (lbaint_t)(*num_bytes / 512) + 1; 5637a7bc39SJason Zhu } else { 5737a7bc39SJason Zhu if (*offset % 512 == 0) { 5837a7bc39SJason Zhu *blkcnt = (lbaint_t)(*num_bytes / 512) + 1; 5937a7bc39SJason Zhu } else { 6037a7bc39SJason Zhu if ((*offset % 512) + (*num_bytes % 512) < 512 || 6137a7bc39SJason Zhu (*offset % 512) + (*num_bytes % 512) == 512) { 6237a7bc39SJason Zhu *blkcnt = (lbaint_t)(*num_bytes / 512) + 1; 6337a7bc39SJason Zhu } else { 6437a7bc39SJason Zhu *blkcnt = (lbaint_t)(*num_bytes / 512) + 2; 6537a7bc39SJason Zhu } 6637a7bc39SJason Zhu } 6737a7bc39SJason Zhu } 6837a7bc39SJason Zhu } 6937a7bc39SJason Zhu 7037a7bc39SJason Zhu static AvbIOResult read_from_partition(AvbOps *ops, 7137a7bc39SJason Zhu const char *partition, 7237a7bc39SJason Zhu int64_t offset, 7337a7bc39SJason Zhu size_t num_bytes, 7437a7bc39SJason Zhu void *buffer, 7537a7bc39SJason Zhu size_t *out_num_read) 7637a7bc39SJason Zhu { 7737a7bc39SJason Zhu struct blk_desc *dev_desc; 7837a7bc39SJason Zhu lbaint_t offset_blk, blkcnt; 7937a7bc39SJason Zhu disk_partition_t part_info; 8037a7bc39SJason Zhu 8137a7bc39SJason Zhu byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt); 82459bc933SJason Zhu dev_desc = rockchip_get_bootdev(); 8337a7bc39SJason Zhu if (!dev_desc) { 84459bc933SJason Zhu printf("%s: Could not find device\n", __func__); 8537a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 8637a7bc39SJason Zhu } 8737a7bc39SJason Zhu 8837a7bc39SJason Zhu if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 8937a7bc39SJason Zhu printf("Could not find \"%s\" partition\n", partition); 9037a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 9137a7bc39SJason Zhu } 9237a7bc39SJason Zhu 9337a7bc39SJason Zhu if ((offset % 512 == 0) && (num_bytes % 512 == 0)) { 947c1937d6SJason Zhu blk_dread(dev_desc, part_info.start + offset_blk, 957c1937d6SJason Zhu blkcnt, buffer); 9637a7bc39SJason Zhu *out_num_read = blkcnt * 512; 9737a7bc39SJason Zhu } else { 9837a7bc39SJason Zhu char *buffer_temp; 997c1937d6SJason Zhu 10037a7bc39SJason Zhu buffer_temp = malloc(512 * blkcnt); 1017c1937d6SJason Zhu if (!buffer_temp) { 10237a7bc39SJason Zhu printf("malloc error!\n"); 10337a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_OOM; 10437a7bc39SJason Zhu } 1057c1937d6SJason Zhu blk_dread(dev_desc, part_info.start + offset_blk, 1067c1937d6SJason Zhu blkcnt, buffer_temp); 10737a7bc39SJason Zhu memcpy(buffer, buffer_temp + (offset % 512), num_bytes); 10837a7bc39SJason Zhu *out_num_read = num_bytes; 10937a7bc39SJason Zhu free(buffer_temp); 11037a7bc39SJason Zhu } 11137a7bc39SJason Zhu 11237a7bc39SJason Zhu return AVB_IO_RESULT_OK; 11337a7bc39SJason Zhu } 11437a7bc39SJason Zhu 11537a7bc39SJason Zhu static AvbIOResult write_to_partition(AvbOps *ops, 11637a7bc39SJason Zhu const char *partition, 11737a7bc39SJason Zhu int64_t offset, 11837a7bc39SJason Zhu size_t num_bytes, 11937a7bc39SJason Zhu const void *buffer) 12037a7bc39SJason Zhu { 12137a7bc39SJason Zhu struct blk_desc *dev_desc; 12237a7bc39SJason Zhu char *buffer_temp; 12337a7bc39SJason Zhu disk_partition_t part_info; 12437a7bc39SJason Zhu lbaint_t offset_blk, blkcnt; 12537a7bc39SJason Zhu 12637a7bc39SJason Zhu byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt); 12737a7bc39SJason Zhu buffer_temp = malloc(512 * blkcnt); 1287c1937d6SJason Zhu if (!buffer_temp) { 12937a7bc39SJason Zhu printf("malloc error!\n"); 13037a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_OOM; 13137a7bc39SJason Zhu } 13237a7bc39SJason Zhu memset(buffer_temp, 0, 512 * blkcnt); 133459bc933SJason Zhu dev_desc = rockchip_get_bootdev(); 13437a7bc39SJason Zhu if (!dev_desc) { 135459bc933SJason Zhu printf("%s: Could not find device\n", __func__); 13637a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 13737a7bc39SJason Zhu } 13837a7bc39SJason Zhu 13937a7bc39SJason Zhu if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 14037a7bc39SJason Zhu printf("Could not find \"%s\" partition\n", partition); 14137a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 14237a7bc39SJason Zhu } 14337a7bc39SJason Zhu 1447c1937d6SJason Zhu if ((offset % 512 != 0) && (num_bytes % 512) != 0) 1457c1937d6SJason Zhu blk_dread(dev_desc, part_info.start + offset_blk, 1467c1937d6SJason Zhu blkcnt, buffer_temp); 14737a7bc39SJason Zhu 14837a7bc39SJason Zhu memcpy(buffer_temp, buffer + (offset % 512), num_bytes); 14937a7bc39SJason Zhu blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer); 15037a7bc39SJason Zhu free(buffer_temp); 15137a7bc39SJason Zhu 15237a7bc39SJason Zhu return AVB_IO_RESULT_OK; 15337a7bc39SJason Zhu } 15437a7bc39SJason Zhu 1557c1937d6SJason Zhu static AvbIOResult 1567c1937d6SJason Zhu validate_vbmeta_public_key(AvbOps *ops, 15737a7bc39SJason Zhu const uint8_t *public_key_data, 15837a7bc39SJason Zhu size_t public_key_length, 15937a7bc39SJason Zhu const uint8_t *public_key_metadata, 16037a7bc39SJason Zhu size_t public_key_metadata_length, 16137a7bc39SJason Zhu bool *out_is_trusted) 16237a7bc39SJason Zhu { 163caed6b4fSJoseph Chen /* remain AVB_VBMETA_PUBLIC_KEY_VALIDATE to compatible legacy code */ 164caed6b4fSJoseph Chen #if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) || \ 165caed6b4fSJoseph Chen defined(AVB_VBMETA_PUBLIC_KEY_VALIDATE) 1667c1937d6SJason Zhu if (out_is_trusted) { 16737a7bc39SJason Zhu avb_atx_validate_vbmeta_public_key(ops, 16837a7bc39SJason Zhu public_key_data, 16937a7bc39SJason Zhu public_key_length, 17037a7bc39SJason Zhu public_key_metadata, 17137a7bc39SJason Zhu public_key_metadata_length, 17237a7bc39SJason Zhu out_is_trusted); 17337a7bc39SJason Zhu } 17437a7bc39SJason Zhu #else 1757c1937d6SJason Zhu if (out_is_trusted) 17637a7bc39SJason Zhu *out_is_trusted = true; 17737a7bc39SJason Zhu #endif 17837a7bc39SJason Zhu return AVB_IO_RESULT_OK; 17937a7bc39SJason Zhu } 18037a7bc39SJason Zhu 18137a7bc39SJason Zhu static AvbIOResult read_rollback_index(AvbOps *ops, 18237a7bc39SJason Zhu size_t rollback_index_location, 18337a7bc39SJason Zhu uint64_t *out_rollback_index) 18437a7bc39SJason Zhu { 1857c1937d6SJason Zhu if (out_rollback_index) { 18637a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 18737a7bc39SJason Zhu int ret; 1887c1937d6SJason Zhu 18937a7bc39SJason Zhu ret = trusty_read_rollback_index(rollback_index_location, 19037a7bc39SJason Zhu out_rollback_index); 1917c1937d6SJason Zhu switch (ret) { 1927c1937d6SJason Zhu case TEE_SUCCESS: 1937c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 1947c1937d6SJason Zhu break; 1957c1937d6SJason Zhu case TEE_ERROR_GENERIC: 1967c1937d6SJason Zhu case TEE_ERROR_NO_DATA: 1977c1937d6SJason Zhu case TEE_ERROR_ITEM_NOT_FOUND: 19837a7bc39SJason Zhu *out_rollback_index = 0; 19937a7bc39SJason Zhu ret = trusty_write_rollback_index(rollback_index_location, 20037a7bc39SJason Zhu *out_rollback_index); 2017c1937d6SJason Zhu if (ret) { 2027c1937d6SJason Zhu printf("%s: init rollback index error\n", 2037c1937d6SJason Zhu __FILE__); 2047c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 20537a7bc39SJason Zhu } else { 2067c1937d6SJason Zhu ret = 2077c1937d6SJason Zhu trusty_read_rollback_index(rollback_index_location, 2087c1937d6SJason Zhu out_rollback_index); 2097c1937d6SJason Zhu if (ret) 2107c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 2117c1937d6SJason Zhu else 2127c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 21337a7bc39SJason Zhu } 2147c1937d6SJason Zhu break; 2157c1937d6SJason Zhu default: 2167c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 2177c1937d6SJason Zhu printf("%s: trusty_read_rollback_index failed", 2187c1937d6SJason Zhu __FILE__); 2197c1937d6SJason Zhu } 2207c1937d6SJason Zhu 2217c1937d6SJason Zhu return ret; 22237a7bc39SJason Zhu #endif 22337a7bc39SJason Zhu } 22437a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 22537a7bc39SJason Zhu } 22637a7bc39SJason Zhu 22737a7bc39SJason Zhu static AvbIOResult write_rollback_index(AvbOps *ops, 22837a7bc39SJason Zhu size_t rollback_index_location, 22937a7bc39SJason Zhu uint64_t rollback_index) 23037a7bc39SJason Zhu { 23137a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 2327c1937d6SJason Zhu if (trusty_write_rollback_index(rollback_index_location, 2337c1937d6SJason Zhu rollback_index)) { 23437a7bc39SJason Zhu printf("%s: Fail to write rollback index\n", __FILE__); 23537a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 23637a7bc39SJason Zhu } 23737a7bc39SJason Zhu return AVB_IO_RESULT_OK; 23837a7bc39SJason Zhu #endif 23937a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 24037a7bc39SJason Zhu } 24137a7bc39SJason Zhu 24237a7bc39SJason Zhu static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) 24337a7bc39SJason Zhu { 2447c1937d6SJason Zhu if (out_is_unlocked) { 24537a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 24637a7bc39SJason Zhu int ret; 24737a7bc39SJason Zhu 24837a7bc39SJason Zhu ret = trusty_read_lock_state((uint8_t *)out_is_unlocked); 2497c1937d6SJason Zhu switch (ret) { 2507c1937d6SJason Zhu case TEE_SUCCESS: 2517c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 2527c1937d6SJason Zhu break; 2537c1937d6SJason Zhu case TEE_ERROR_GENERIC: 2547c1937d6SJason Zhu case TEE_ERROR_NO_DATA: 2557c1937d6SJason Zhu case TEE_ERROR_ITEM_NOT_FOUND: 25637a7bc39SJason Zhu *out_is_unlocked = 1; 25737a7bc39SJason Zhu if (trusty_write_lock_state(*out_is_unlocked)) { 25837a7bc39SJason Zhu printf("%s: init lock state error\n", __FILE__); 2597c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 26037a7bc39SJason Zhu } else { 2617c1937d6SJason Zhu ret = 2627c1937d6SJason Zhu trusty_read_lock_state((uint8_t *)out_is_unlocked); 2637c1937d6SJason Zhu if (ret == 0) 2647c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 2657c1937d6SJason Zhu else 2667c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 26737a7bc39SJason Zhu } 2687c1937d6SJason Zhu break; 2697c1937d6SJason Zhu default: 2707c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 2717c1937d6SJason Zhu printf("%s: trusty_read_lock_state failed\n", __FILE__); 2727c1937d6SJason Zhu } 2737c1937d6SJason Zhu return ret; 27437a7bc39SJason Zhu #endif 27537a7bc39SJason Zhu } 27637a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 27737a7bc39SJason Zhu } 27837a7bc39SJason Zhu 27937a7bc39SJason Zhu static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) 28037a7bc39SJason Zhu { 2817c1937d6SJason Zhu if (out_is_unlocked) { 28237a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 28337a7bc39SJason Zhu if (trusty_write_lock_state(*out_is_unlocked)) { 28437a7bc39SJason Zhu printf("%s: Fail to write lock state\n", __FILE__); 28537a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 28637a7bc39SJason Zhu } 28737a7bc39SJason Zhu return AVB_IO_RESULT_OK; 28837a7bc39SJason Zhu #endif 28937a7bc39SJason Zhu } 29037a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 29137a7bc39SJason Zhu } 29237a7bc39SJason Zhu 29337a7bc39SJason Zhu static AvbIOResult get_size_of_partition(AvbOps *ops, 29437a7bc39SJason Zhu const char *partition, 29537a7bc39SJason Zhu uint64_t *out_size_in_bytes) 29637a7bc39SJason Zhu { 29737a7bc39SJason Zhu struct blk_desc *dev_desc; 29837a7bc39SJason Zhu disk_partition_t part_info; 29937a7bc39SJason Zhu 300459bc933SJason Zhu dev_desc = rockchip_get_bootdev(); 30137a7bc39SJason Zhu if (!dev_desc) { 302459bc933SJason Zhu printf("%s: Could not find device\n", __func__); 30337a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 30437a7bc39SJason Zhu } 30537a7bc39SJason Zhu 30637a7bc39SJason Zhu if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 30737a7bc39SJason Zhu printf("Could not find \"%s\" partition\n", partition); 30837a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 30937a7bc39SJason Zhu } 31037a7bc39SJason Zhu *out_size_in_bytes = (part_info.size) * 512; 31137a7bc39SJason Zhu return AVB_IO_RESULT_OK; 31237a7bc39SJason Zhu } 31337a7bc39SJason Zhu 31437a7bc39SJason Zhu static AvbIOResult get_unique_guid_for_partition(AvbOps *ops, 31537a7bc39SJason Zhu const char *partition, 31637a7bc39SJason Zhu char *guid_buf, 31737a7bc39SJason Zhu size_t guid_buf_size) 31837a7bc39SJason Zhu { 31937a7bc39SJason Zhu struct blk_desc *dev_desc; 32037a7bc39SJason Zhu disk_partition_t part_info; 3217c1937d6SJason Zhu 322459bc933SJason Zhu dev_desc = rockchip_get_bootdev(); 32337a7bc39SJason Zhu if (!dev_desc) { 324459bc933SJason Zhu printf("%s: Could not find device\n", __func__); 32537a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 32637a7bc39SJason Zhu } 32737a7bc39SJason Zhu 32837a7bc39SJason Zhu if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 32937a7bc39SJason Zhu printf("Could not find \"%s\" partition\n", partition); 33037a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 33137a7bc39SJason Zhu } 3327c1937d6SJason Zhu if (guid_buf && guid_buf_size > 0) 33337a7bc39SJason Zhu memcpy(guid_buf, part_info.uuid, guid_buf_size); 3347c1937d6SJason Zhu 33537a7bc39SJason Zhu return AVB_IO_RESULT_OK; 33637a7bc39SJason Zhu } 33737a7bc39SJason Zhu 33837a7bc39SJason Zhu /* read permanent attributes from rpmb */ 33937a7bc39SJason Zhu AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops, 34037a7bc39SJason Zhu AvbAtxPermanentAttributes *attributes) 34137a7bc39SJason Zhu { 3427c1937d6SJason Zhu if (attributes) { 34337a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 34437a7bc39SJason Zhu trusty_read_permanent_attributes((uint8_t *)attributes, 34537a7bc39SJason Zhu sizeof(struct AvbAtxPermanentAttributes)); 34637a7bc39SJason Zhu return AVB_IO_RESULT_OK; 34737a7bc39SJason Zhu #endif 34837a7bc39SJason Zhu } 34937a7bc39SJason Zhu 35037a7bc39SJason Zhu return -1; 35137a7bc39SJason Zhu } 35237a7bc39SJason Zhu 35337a7bc39SJason Zhu /*read permanent attributes hash from efuse */ 35437a7bc39SJason Zhu AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops, 35537a7bc39SJason Zhu uint8_t hash[AVB_SHA256_DIGEST_SIZE]) 35637a7bc39SJason Zhu { 35774b485fbSJason Zhu #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY 35837a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 3597c1937d6SJason Zhu if (trusty_read_attribute_hash((uint32_t *)hash, 3607c1937d6SJason Zhu AVB_SHA256_DIGEST_SIZE / 4)) 36137a7bc39SJason Zhu return -1; 36237a7bc39SJason Zhu #else 36337a7bc39SJason Zhu avb_error("Please open the macro!\n"); 36437a7bc39SJason Zhu return -1; 36537a7bc39SJason Zhu #endif 36665f0143bSJason Zhu #endif 36737a7bc39SJason Zhu return AVB_IO_RESULT_OK; 36837a7bc39SJason Zhu } 36937a7bc39SJason Zhu 37082e713e1SJason Zhu static void avb_set_key_version(AvbAtxOps *atx_ops, 37182e713e1SJason Zhu size_t rollback_index_location, 37282e713e1SJason Zhu uint64_t key_version) 37382e713e1SJason Zhu { 37482e713e1SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 375ee9d3433SJason Zhu uint64_t key_version_temp = 0; 376ee9d3433SJason Zhu 377ee9d3433SJason Zhu if (trusty_read_rollback_index(rollback_index_location, &key_version_temp)) 378ee9d3433SJason Zhu printf("%s: Fail to read rollback index\n", __FILE__); 379ee9d3433SJason Zhu if (key_version_temp == key_version) 380ee9d3433SJason Zhu return; 3817c1937d6SJason Zhu if (trusty_write_rollback_index(rollback_index_location, key_version)) 38282e713e1SJason Zhu printf("%s: Fail to write rollback index\n", __FILE__); 38382e713e1SJason Zhu #endif 38482e713e1SJason Zhu } 38582e713e1SJason Zhu 3868d0db1d9SJason Zhu AvbIOResult rk_get_random(AvbAtxOps *atx_ops, 3878d0db1d9SJason Zhu size_t num_bytes, 3888d0db1d9SJason Zhu uint8_t *output) 3898d0db1d9SJason Zhu { 3908d0db1d9SJason Zhu int i; 3918d0db1d9SJason Zhu unsigned int seed; 3928d0db1d9SJason Zhu 3938d0db1d9SJason Zhu seed = (unsigned int)get_timer(0); 3948d0db1d9SJason Zhu for (i = 0; i < num_bytes; i++) { 3958d0db1d9SJason Zhu srand(seed); 3968d0db1d9SJason Zhu output[i] = (uint8_t)(rand()); 3978d0db1d9SJason Zhu seed = (unsigned int)(output[i]); 3988d0db1d9SJason Zhu } 3998d0db1d9SJason Zhu 4008d0db1d9SJason Zhu return 0; 4018d0db1d9SJason Zhu } 4028d0db1d9SJason Zhu 403*27e62cd7SJoseph Chen #ifdef CONFIG_ANDROID_BOOT_IMAGE 404*27e62cd7SJoseph Chen static AvbIOResult get_preloaded_partition(AvbOps* ops, 405*27e62cd7SJoseph Chen const char* partition, 406*27e62cd7SJoseph Chen size_t num_bytes, 407*27e62cd7SJoseph Chen uint8_t** out_pointer, 408*27e62cd7SJoseph Chen size_t* out_num_bytes_preloaded, 409*27e62cd7SJoseph Chen int allow_verification_error) 410*27e62cd7SJoseph Chen { 411*27e62cd7SJoseph Chen struct blk_desc *dev_desc; 412*27e62cd7SJoseph Chen ulong load_addr; 413*27e62cd7SJoseph Chen int ret; 414*27e62cd7SJoseph Chen 415*27e62cd7SJoseph Chen /* no need go further */ 416*27e62cd7SJoseph Chen if (!allow_verification_error) 417*27e62cd7SJoseph Chen return AVB_IO_RESULT_OK; 418*27e62cd7SJoseph Chen 419*27e62cd7SJoseph Chen printf("get image from preloaded partition...\n"); 420*27e62cd7SJoseph Chen dev_desc = rockchip_get_bootdev(); 421*27e62cd7SJoseph Chen if (!dev_desc) 422*27e62cd7SJoseph Chen return AVB_SLOT_VERIFY_RESULT_ERROR_IO; 423*27e62cd7SJoseph Chen 424*27e62cd7SJoseph Chen load_addr = env_get_ulong("kernel_addr_r", 16, 0); 425*27e62cd7SJoseph Chen if (!load_addr) 426*27e62cd7SJoseph Chen return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; 427*27e62cd7SJoseph Chen 428*27e62cd7SJoseph Chen ret = android_image_load_by_partname(dev_desc, partition, &load_addr); 429*27e62cd7SJoseph Chen if (!ret) { 430*27e62cd7SJoseph Chen *out_pointer = (u8 *)load_addr; 431*27e62cd7SJoseph Chen *out_num_bytes_preloaded = num_bytes; /* return what it expects */ 432*27e62cd7SJoseph Chen ret = AVB_SLOT_VERIFY_RESULT_OK; 433*27e62cd7SJoseph Chen } else { 434*27e62cd7SJoseph Chen ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; 435*27e62cd7SJoseph Chen } 436*27e62cd7SJoseph Chen 437*27e62cd7SJoseph Chen return ret; 438*27e62cd7SJoseph Chen } 439*27e62cd7SJoseph Chen #endif 440*27e62cd7SJoseph Chen 4417c1937d6SJason Zhu AvbOps *avb_ops_user_new(void) 4427c1937d6SJason Zhu { 44337a7bc39SJason Zhu AvbOps *ops; 44437a7bc39SJason Zhu 44537a7bc39SJason Zhu ops = calloc(1, sizeof(AvbOps)); 4467c1937d6SJason Zhu if (!ops) { 44737a7bc39SJason Zhu avb_error("Error allocating memory for AvbOps.\n"); 44837a7bc39SJason Zhu goto out; 44937a7bc39SJason Zhu } 45037a7bc39SJason Zhu ops->ab_ops = calloc(1, sizeof(AvbABOps)); 4517c1937d6SJason Zhu if (!ops->ab_ops) { 45237a7bc39SJason Zhu avb_error("Error allocating memory for AvbABOps.\n"); 45337a7bc39SJason Zhu free(ops); 45437a7bc39SJason Zhu goto out; 45537a7bc39SJason Zhu } 45637a7bc39SJason Zhu 45737a7bc39SJason Zhu ops->atx_ops = calloc(1, sizeof(AvbAtxOps)); 4587c1937d6SJason Zhu if (!ops->atx_ops) { 45937a7bc39SJason Zhu avb_error("Error allocating memory for AvbAtxOps.\n"); 46037a7bc39SJason Zhu free(ops->ab_ops); 46137a7bc39SJason Zhu free(ops); 46237a7bc39SJason Zhu goto out; 46337a7bc39SJason Zhu } 46437a7bc39SJason Zhu ops->ab_ops->ops = ops; 46537a7bc39SJason Zhu ops->atx_ops->ops = ops; 46637a7bc39SJason Zhu 46737a7bc39SJason Zhu ops->read_from_partition = read_from_partition; 46837a7bc39SJason Zhu ops->write_to_partition = write_to_partition; 46937a7bc39SJason Zhu ops->validate_vbmeta_public_key = validate_vbmeta_public_key; 47037a7bc39SJason Zhu ops->read_rollback_index = read_rollback_index; 47137a7bc39SJason Zhu ops->write_rollback_index = write_rollback_index; 47237a7bc39SJason Zhu ops->read_is_device_unlocked = read_is_device_unlocked; 47337a7bc39SJason Zhu ops->write_is_device_unlocked = write_is_device_unlocked; 47437a7bc39SJason Zhu ops->get_unique_guid_for_partition = get_unique_guid_for_partition; 47537a7bc39SJason Zhu ops->get_size_of_partition = get_size_of_partition; 476*27e62cd7SJoseph Chen #ifdef CONFIG_ANDROID_BOOT_IMAGE 477*27e62cd7SJoseph Chen ops->get_preloaded_partition = get_preloaded_partition; 478*27e62cd7SJoseph Chen #endif 47937a7bc39SJason Zhu ops->ab_ops->read_ab_metadata = avb_ab_data_read; 48037a7bc39SJason Zhu ops->ab_ops->write_ab_metadata = avb_ab_data_write; 48137a7bc39SJason Zhu ops->atx_ops->read_permanent_attributes = avb_read_perm_attr; 48237a7bc39SJason Zhu ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash; 48382e713e1SJason Zhu ops->atx_ops->set_key_version = avb_set_key_version; 4848d0db1d9SJason Zhu ops->atx_ops->get_random = rk_get_random; 48537a7bc39SJason Zhu 48637a7bc39SJason Zhu out: 48737a7bc39SJason Zhu return ops; 48837a7bc39SJason Zhu } 48937a7bc39SJason Zhu 4907c1937d6SJason Zhu void avb_ops_user_free(AvbOps *ops) 4917c1937d6SJason Zhu { 49237a7bc39SJason Zhu free(ops->ab_ops); 49337a7bc39SJason Zhu free(ops->atx_ops); 49437a7bc39SJason Zhu free(ops); 49537a7bc39SJason Zhu } 496