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) { 52*7c1937d6SJason Zhu if (*offset % 512 == 0) 5337a7bc39SJason Zhu *blkcnt = (lbaint_t)(*num_bytes / 512); 54*7c1937d6SJason 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)) { 94*7c1937d6SJason Zhu blk_dread(dev_desc, part_info.start + offset_blk, 95*7c1937d6SJason Zhu blkcnt, buffer); 9637a7bc39SJason Zhu *out_num_read = blkcnt * 512; 9737a7bc39SJason Zhu } else { 9837a7bc39SJason Zhu char *buffer_temp; 99*7c1937d6SJason Zhu 10037a7bc39SJason Zhu buffer_temp = malloc(512 * blkcnt); 101*7c1937d6SJason Zhu if (!buffer_temp) { 10237a7bc39SJason Zhu printf("malloc error!\n"); 10337a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_OOM; 10437a7bc39SJason Zhu } 105*7c1937d6SJason Zhu blk_dread(dev_desc, part_info.start + offset_blk, 106*7c1937d6SJason 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); 128*7c1937d6SJason 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 144*7c1937d6SJason Zhu if ((offset % 512 != 0) && (num_bytes % 512) != 0) 145*7c1937d6SJason Zhu blk_dread(dev_desc, part_info.start + offset_blk, 146*7c1937d6SJason 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 155*7c1937d6SJason Zhu static AvbIOResult 156*7c1937d6SJason 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 { 16337a7bc39SJason Zhu #ifdef AVB_VBMETA_PUBLIC_KEY_VALIDATE 164*7c1937d6SJason Zhu if (out_is_trusted) { 16537a7bc39SJason Zhu avb_atx_validate_vbmeta_public_key(ops, 16637a7bc39SJason Zhu public_key_data, 16737a7bc39SJason Zhu public_key_length, 16837a7bc39SJason Zhu public_key_metadata, 16937a7bc39SJason Zhu public_key_metadata_length, 17037a7bc39SJason Zhu out_is_trusted); 17137a7bc39SJason Zhu } 17237a7bc39SJason Zhu #else 173*7c1937d6SJason Zhu if (out_is_trusted) 17437a7bc39SJason Zhu *out_is_trusted = true; 17537a7bc39SJason Zhu #endif 17637a7bc39SJason Zhu return AVB_IO_RESULT_OK; 17737a7bc39SJason Zhu } 17837a7bc39SJason Zhu 17937a7bc39SJason Zhu static AvbIOResult read_rollback_index(AvbOps *ops, 18037a7bc39SJason Zhu size_t rollback_index_location, 18137a7bc39SJason Zhu uint64_t *out_rollback_index) 18237a7bc39SJason Zhu { 183*7c1937d6SJason Zhu if (out_rollback_index) { 18437a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 18537a7bc39SJason Zhu int ret; 186*7c1937d6SJason Zhu 18737a7bc39SJason Zhu ret = trusty_read_rollback_index(rollback_index_location, 18837a7bc39SJason Zhu out_rollback_index); 189*7c1937d6SJason Zhu switch (ret) { 190*7c1937d6SJason Zhu case TEE_SUCCESS: 191*7c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 192*7c1937d6SJason Zhu break; 193*7c1937d6SJason Zhu case TEE_ERROR_GENERIC: 194*7c1937d6SJason Zhu case TEE_ERROR_NO_DATA: 195*7c1937d6SJason Zhu case TEE_ERROR_ITEM_NOT_FOUND: 19637a7bc39SJason Zhu *out_rollback_index = 0; 19737a7bc39SJason Zhu ret = trusty_write_rollback_index(rollback_index_location, 19837a7bc39SJason Zhu *out_rollback_index); 199*7c1937d6SJason Zhu if (ret) { 200*7c1937d6SJason Zhu printf("%s: init rollback index error\n", 201*7c1937d6SJason Zhu __FILE__); 202*7c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 20337a7bc39SJason Zhu } else { 204*7c1937d6SJason Zhu ret = 205*7c1937d6SJason Zhu trusty_read_rollback_index(rollback_index_location, 206*7c1937d6SJason Zhu out_rollback_index); 207*7c1937d6SJason Zhu if (ret) 208*7c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 209*7c1937d6SJason Zhu else 210*7c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 21137a7bc39SJason Zhu } 212*7c1937d6SJason Zhu break; 213*7c1937d6SJason Zhu default: 214*7c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 215*7c1937d6SJason Zhu printf("%s: trusty_read_rollback_index failed", 216*7c1937d6SJason Zhu __FILE__); 217*7c1937d6SJason Zhu } 218*7c1937d6SJason Zhu 219*7c1937d6SJason Zhu return ret; 22037a7bc39SJason Zhu #endif 22137a7bc39SJason Zhu } 22237a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 22337a7bc39SJason Zhu } 22437a7bc39SJason Zhu 22537a7bc39SJason Zhu static AvbIOResult write_rollback_index(AvbOps *ops, 22637a7bc39SJason Zhu size_t rollback_index_location, 22737a7bc39SJason Zhu uint64_t rollback_index) 22837a7bc39SJason Zhu { 22937a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 230*7c1937d6SJason Zhu if (trusty_write_rollback_index(rollback_index_location, 231*7c1937d6SJason Zhu rollback_index)) { 23237a7bc39SJason Zhu printf("%s: Fail to write rollback index\n", __FILE__); 23337a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 23437a7bc39SJason Zhu } 23537a7bc39SJason Zhu return AVB_IO_RESULT_OK; 23637a7bc39SJason Zhu #endif 23737a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 23837a7bc39SJason Zhu } 23937a7bc39SJason Zhu 24037a7bc39SJason Zhu static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) 24137a7bc39SJason Zhu { 242*7c1937d6SJason Zhu if (out_is_unlocked) { 24337a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 24437a7bc39SJason Zhu int ret; 24537a7bc39SJason Zhu 24637a7bc39SJason Zhu ret = trusty_read_lock_state((uint8_t *)out_is_unlocked); 247*7c1937d6SJason Zhu switch (ret) { 248*7c1937d6SJason Zhu case TEE_SUCCESS: 249*7c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 250*7c1937d6SJason Zhu break; 251*7c1937d6SJason Zhu case TEE_ERROR_GENERIC: 252*7c1937d6SJason Zhu case TEE_ERROR_NO_DATA: 253*7c1937d6SJason Zhu case TEE_ERROR_ITEM_NOT_FOUND: 25437a7bc39SJason Zhu *out_is_unlocked = 1; 25537a7bc39SJason Zhu if (trusty_write_lock_state(*out_is_unlocked)) { 25637a7bc39SJason Zhu printf("%s: init lock state error\n", __FILE__); 257*7c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 25837a7bc39SJason Zhu } else { 259*7c1937d6SJason Zhu ret = 260*7c1937d6SJason Zhu trusty_read_lock_state((uint8_t *)out_is_unlocked); 261*7c1937d6SJason Zhu if (ret == 0) 262*7c1937d6SJason Zhu ret = AVB_IO_RESULT_OK; 263*7c1937d6SJason Zhu else 264*7c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 26537a7bc39SJason Zhu } 266*7c1937d6SJason Zhu break; 267*7c1937d6SJason Zhu default: 268*7c1937d6SJason Zhu ret = AVB_IO_RESULT_ERROR_IO; 269*7c1937d6SJason Zhu printf("%s: trusty_read_lock_state failed\n", __FILE__); 270*7c1937d6SJason Zhu } 271*7c1937d6SJason Zhu return ret; 27237a7bc39SJason Zhu #endif 27337a7bc39SJason Zhu } 27437a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 27537a7bc39SJason Zhu } 27637a7bc39SJason Zhu 27737a7bc39SJason Zhu static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) 27837a7bc39SJason Zhu { 279*7c1937d6SJason Zhu if (out_is_unlocked) { 28037a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 28137a7bc39SJason Zhu if (trusty_write_lock_state(*out_is_unlocked)) { 28237a7bc39SJason Zhu printf("%s: Fail to write lock state\n", __FILE__); 28337a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 28437a7bc39SJason Zhu } 28537a7bc39SJason Zhu return AVB_IO_RESULT_OK; 28637a7bc39SJason Zhu #endif 28737a7bc39SJason Zhu } 28837a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_IO; 28937a7bc39SJason Zhu } 29037a7bc39SJason Zhu 29137a7bc39SJason Zhu static AvbIOResult get_size_of_partition(AvbOps *ops, 29237a7bc39SJason Zhu const char *partition, 29337a7bc39SJason Zhu uint64_t *out_size_in_bytes) 29437a7bc39SJason Zhu { 29537a7bc39SJason Zhu struct blk_desc *dev_desc; 29637a7bc39SJason Zhu disk_partition_t part_info; 29737a7bc39SJason Zhu 298459bc933SJason Zhu dev_desc = rockchip_get_bootdev(); 29937a7bc39SJason Zhu if (!dev_desc) { 300459bc933SJason Zhu printf("%s: Could not find device\n", __func__); 30137a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 30237a7bc39SJason Zhu } 30337a7bc39SJason Zhu 30437a7bc39SJason Zhu if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 30537a7bc39SJason Zhu printf("Could not find \"%s\" partition\n", partition); 30637a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 30737a7bc39SJason Zhu } 30837a7bc39SJason Zhu *out_size_in_bytes = (part_info.size) * 512; 30937a7bc39SJason Zhu return AVB_IO_RESULT_OK; 31037a7bc39SJason Zhu } 31137a7bc39SJason Zhu 31237a7bc39SJason Zhu static AvbIOResult get_unique_guid_for_partition(AvbOps *ops, 31337a7bc39SJason Zhu const char *partition, 31437a7bc39SJason Zhu char *guid_buf, 31537a7bc39SJason Zhu size_t guid_buf_size) 31637a7bc39SJason Zhu { 31737a7bc39SJason Zhu struct blk_desc *dev_desc; 31837a7bc39SJason Zhu disk_partition_t part_info; 319*7c1937d6SJason Zhu 320459bc933SJason Zhu dev_desc = rockchip_get_bootdev(); 32137a7bc39SJason Zhu if (!dev_desc) { 322459bc933SJason Zhu printf("%s: Could not find device\n", __func__); 32337a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 32437a7bc39SJason Zhu } 32537a7bc39SJason Zhu 32637a7bc39SJason Zhu if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 32737a7bc39SJason Zhu printf("Could not find \"%s\" partition\n", partition); 32837a7bc39SJason Zhu return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 32937a7bc39SJason Zhu } 330*7c1937d6SJason Zhu if (guid_buf && guid_buf_size > 0) 33137a7bc39SJason Zhu memcpy(guid_buf, part_info.uuid, guid_buf_size); 332*7c1937d6SJason Zhu 33337a7bc39SJason Zhu return AVB_IO_RESULT_OK; 33437a7bc39SJason Zhu } 33537a7bc39SJason Zhu 33637a7bc39SJason Zhu /* read permanent attributes from rpmb */ 33737a7bc39SJason Zhu AvbIOResult avb_read_perm_attr(AvbAtxOps *atx_ops, 33837a7bc39SJason Zhu AvbAtxPermanentAttributes *attributes) 33937a7bc39SJason Zhu { 340*7c1937d6SJason Zhu if (attributes) { 34137a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 34237a7bc39SJason Zhu trusty_read_permanent_attributes((uint8_t *)attributes, 34337a7bc39SJason Zhu sizeof(struct AvbAtxPermanentAttributes)); 34437a7bc39SJason Zhu return AVB_IO_RESULT_OK; 34537a7bc39SJason Zhu #endif 34637a7bc39SJason Zhu } 34737a7bc39SJason Zhu 34837a7bc39SJason Zhu return -1; 34937a7bc39SJason Zhu } 35037a7bc39SJason Zhu 35137a7bc39SJason Zhu /*read permanent attributes hash from efuse */ 35237a7bc39SJason Zhu AvbIOResult avb_read_perm_attr_hash(AvbAtxOps *atx_ops, 35337a7bc39SJason Zhu uint8_t hash[AVB_SHA256_DIGEST_SIZE]) 35437a7bc39SJason Zhu { 35537a7bc39SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 356*7c1937d6SJason Zhu if (trusty_read_attribute_hash((uint32_t *)hash, 357*7c1937d6SJason Zhu AVB_SHA256_DIGEST_SIZE / 4)) 35837a7bc39SJason Zhu return -1; 35937a7bc39SJason Zhu #else 36037a7bc39SJason Zhu avb_error("Please open the macro!\n"); 36137a7bc39SJason Zhu return -1; 36237a7bc39SJason Zhu #endif 36337a7bc39SJason Zhu return AVB_IO_RESULT_OK; 36437a7bc39SJason Zhu } 36537a7bc39SJason Zhu 36682e713e1SJason Zhu static void avb_set_key_version(AvbAtxOps *atx_ops, 36782e713e1SJason Zhu size_t rollback_index_location, 36882e713e1SJason Zhu uint64_t key_version) 36982e713e1SJason Zhu { 37082e713e1SJason Zhu #ifdef CONFIG_OPTEE_CLIENT 371*7c1937d6SJason Zhu if (trusty_write_rollback_index(rollback_index_location, key_version)) 37282e713e1SJason Zhu printf("%s: Fail to write rollback index\n", __FILE__); 37382e713e1SJason Zhu #endif 37482e713e1SJason Zhu } 37582e713e1SJason Zhu 3768d0db1d9SJason Zhu AvbIOResult rk_get_random(AvbAtxOps *atx_ops, 3778d0db1d9SJason Zhu size_t num_bytes, 3788d0db1d9SJason Zhu uint8_t *output) 3798d0db1d9SJason Zhu { 3808d0db1d9SJason Zhu int i; 3818d0db1d9SJason Zhu unsigned int seed; 3828d0db1d9SJason Zhu 3838d0db1d9SJason Zhu seed = (unsigned int)get_timer(0); 3848d0db1d9SJason Zhu for (i = 0; i < num_bytes; i++) { 3858d0db1d9SJason Zhu srand(seed); 3868d0db1d9SJason Zhu output[i] = (uint8_t)(rand()); 3878d0db1d9SJason Zhu seed = (unsigned int)(output[i]); 3888d0db1d9SJason Zhu } 3898d0db1d9SJason Zhu 3908d0db1d9SJason Zhu return 0; 3918d0db1d9SJason Zhu } 3928d0db1d9SJason Zhu 393*7c1937d6SJason Zhu AvbOps *avb_ops_user_new(void) 394*7c1937d6SJason Zhu { 39537a7bc39SJason Zhu AvbOps *ops; 39637a7bc39SJason Zhu 39737a7bc39SJason Zhu ops = calloc(1, sizeof(AvbOps)); 398*7c1937d6SJason Zhu if (!ops) { 39937a7bc39SJason Zhu avb_error("Error allocating memory for AvbOps.\n"); 40037a7bc39SJason Zhu goto out; 40137a7bc39SJason Zhu } 40237a7bc39SJason Zhu ops->ab_ops = calloc(1, sizeof(AvbABOps)); 403*7c1937d6SJason Zhu if (!ops->ab_ops) { 40437a7bc39SJason Zhu avb_error("Error allocating memory for AvbABOps.\n"); 40537a7bc39SJason Zhu free(ops); 40637a7bc39SJason Zhu goto out; 40737a7bc39SJason Zhu } 40837a7bc39SJason Zhu 40937a7bc39SJason Zhu ops->atx_ops = calloc(1, sizeof(AvbAtxOps)); 410*7c1937d6SJason Zhu if (!ops->atx_ops) { 41137a7bc39SJason Zhu avb_error("Error allocating memory for AvbAtxOps.\n"); 41237a7bc39SJason Zhu free(ops->ab_ops); 41337a7bc39SJason Zhu free(ops); 41437a7bc39SJason Zhu goto out; 41537a7bc39SJason Zhu } 41637a7bc39SJason Zhu ops->ab_ops->ops = ops; 41737a7bc39SJason Zhu ops->atx_ops->ops = ops; 41837a7bc39SJason Zhu 41937a7bc39SJason Zhu ops->read_from_partition = read_from_partition; 42037a7bc39SJason Zhu ops->write_to_partition = write_to_partition; 42137a7bc39SJason Zhu ops->validate_vbmeta_public_key = validate_vbmeta_public_key; 42237a7bc39SJason Zhu ops->read_rollback_index = read_rollback_index; 42337a7bc39SJason Zhu ops->write_rollback_index = write_rollback_index; 42437a7bc39SJason Zhu ops->read_is_device_unlocked = read_is_device_unlocked; 42537a7bc39SJason Zhu ops->write_is_device_unlocked = write_is_device_unlocked; 42637a7bc39SJason Zhu ops->get_unique_guid_for_partition = get_unique_guid_for_partition; 42737a7bc39SJason Zhu ops->get_size_of_partition = get_size_of_partition; 42837a7bc39SJason Zhu ops->ab_ops->read_ab_metadata = avb_ab_data_read; 42937a7bc39SJason Zhu ops->ab_ops->write_ab_metadata = avb_ab_data_write; 43037a7bc39SJason Zhu ops->atx_ops->read_permanent_attributes = avb_read_perm_attr; 43137a7bc39SJason Zhu ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash; 43282e713e1SJason Zhu ops->atx_ops->set_key_version = avb_set_key_version; 4338d0db1d9SJason Zhu ops->atx_ops->get_random = rk_get_random; 43437a7bc39SJason Zhu 43537a7bc39SJason Zhu out: 43637a7bc39SJason Zhu return ops; 43737a7bc39SJason Zhu } 43837a7bc39SJason Zhu 439*7c1937d6SJason Zhu void avb_ops_user_free(AvbOps *ops) 440*7c1937d6SJason Zhu { 44137a7bc39SJason Zhu free(ops->ab_ops); 44237a7bc39SJason Zhu free(ops->atx_ops); 44337a7bc39SJason Zhu free(ops); 44437a7bc39SJason Zhu } 445