1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include <common.h> 26 #include <image.h> 27 #include <android_image.h> 28 #include <malloc.h> 29 #include <mapmem.h> 30 #include <errno.h> 31 #include <command.h> 32 #include <mmc.h> 33 #include <blk.h> 34 #include <part.h> 35 #include <android_avb/avb_ops_user.h> 36 #include <android_avb/libavb_ab.h> 37 #include <android_avb/avb_atx_validate.h> 38 #include <android_avb/avb_atx_types.h> 39 #include <optee_include/OpteeClientInterface.h> 40 #include <optee_include/tee_api_defines.h> 41 #include <android_avb/avb_vbmeta_image.h> 42 #include <android_avb/avb_atx_validate.h> 43 #include <boot_rkimg.h> 44 45 static void byte_to_block(int64_t *offset, 46 size_t *num_bytes, 47 lbaint_t *offset_blk, 48 lbaint_t *blkcnt) 49 { 50 *offset_blk = (lbaint_t)(*offset / 512); 51 if (*num_bytes % 512 == 0) { 52 if (*offset % 512 == 0) { 53 *blkcnt = (lbaint_t)(*num_bytes / 512); 54 } else { 55 *blkcnt = (lbaint_t)(*num_bytes / 512) + 1; 56 } 57 } else { 58 if (*offset % 512 == 0) { 59 *blkcnt = (lbaint_t)(*num_bytes / 512) + 1; 60 } else { 61 if ((*offset % 512) + (*num_bytes % 512) < 512 || 62 (*offset % 512) + (*num_bytes % 512) == 512) { 63 *blkcnt = (lbaint_t)(*num_bytes / 512) + 1; 64 } else { 65 *blkcnt = (lbaint_t)(*num_bytes / 512) + 2; 66 } 67 } 68 } 69 } 70 71 static AvbIOResult read_from_partition(AvbOps* ops, 72 const char* partition, 73 int64_t offset, 74 size_t num_bytes, 75 void* buffer, 76 size_t* out_num_read) 77 { 78 struct blk_desc *dev_desc; 79 lbaint_t offset_blk, blkcnt; 80 disk_partition_t part_info; 81 82 byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt); 83 dev_desc = rockchip_get_bootdev(); 84 if (!dev_desc) { 85 printf("%s: Could not find device\n", __func__); 86 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 87 } 88 89 if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 90 printf("Could not find \"%s\" partition\n", partition); 91 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 92 } 93 94 if((offset % 512 == 0) && (num_bytes % 512 == 0)) { 95 blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer); 96 *out_num_read = blkcnt * 512; 97 } else { 98 char *buffer_temp; 99 buffer_temp = malloc(512 * blkcnt); 100 if (buffer_temp == NULL) { 101 printf("malloc error!\n"); 102 return AVB_IO_RESULT_ERROR_OOM; 103 } 104 blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp); 105 memcpy(buffer, buffer_temp + (offset % 512), num_bytes); 106 *out_num_read = num_bytes; 107 free(buffer_temp); 108 } 109 110 return AVB_IO_RESULT_OK; 111 } 112 113 static AvbIOResult write_to_partition(AvbOps* ops, 114 const char* partition, 115 int64_t offset, 116 size_t num_bytes, 117 const void* buffer) 118 { 119 struct blk_desc *dev_desc; 120 char *buffer_temp; 121 disk_partition_t part_info; 122 lbaint_t offset_blk, blkcnt; 123 124 byte_to_block(&offset, &num_bytes, &offset_blk, &blkcnt); 125 buffer_temp = malloc(512 * blkcnt); 126 if (buffer_temp == NULL) { 127 printf("malloc error!\n"); 128 return AVB_IO_RESULT_ERROR_OOM; 129 } 130 memset(buffer_temp, 0, 512 * blkcnt); 131 dev_desc = rockchip_get_bootdev(); 132 if (!dev_desc) { 133 printf("%s: Could not find device\n", __func__); 134 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 135 } 136 137 if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 138 printf("Could not find \"%s\" partition\n", partition); 139 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 140 } 141 142 if ((offset % 512 != 0) && (num_bytes % 512) != 0) { 143 blk_dread(dev_desc, part_info.start + offset_blk, blkcnt, buffer_temp); 144 } 145 146 memcpy(buffer_temp, buffer + (offset % 512), num_bytes); 147 blk_dwrite(dev_desc, part_info.start + offset_blk, blkcnt, buffer); 148 free(buffer_temp); 149 150 return AVB_IO_RESULT_OK; 151 } 152 153 static AvbIOResult validate_vbmeta_public_key( 154 AvbOps *ops, 155 const uint8_t *public_key_data, 156 size_t public_key_length, 157 const uint8_t *public_key_metadata, 158 size_t public_key_metadata_length, 159 bool *out_is_trusted) 160 { 161 #ifdef AVB_VBMETA_PUBLIC_KEY_VALIDATE 162 if (out_is_trusted != NULL) { 163 avb_atx_validate_vbmeta_public_key(ops, 164 public_key_data, 165 public_key_length, 166 public_key_metadata, 167 public_key_metadata_length, 168 out_is_trusted); 169 } 170 #else 171 if (out_is_trusted != NULL) { 172 *out_is_trusted = true; 173 } 174 #endif 175 return AVB_IO_RESULT_OK; 176 } 177 178 static AvbIOResult read_rollback_index(AvbOps *ops, 179 size_t rollback_index_location, 180 uint64_t *out_rollback_index) 181 { 182 if (out_rollback_index != NULL) { 183 #ifdef CONFIG_OPTEE_CLIENT 184 int ret; 185 ret = trusty_read_rollback_index(rollback_index_location, 186 out_rollback_index); 187 if (ret == TEE_ERROR_ITEM_NOT_FOUND) { 188 *out_rollback_index = 0; 189 ret = trusty_write_rollback_index(rollback_index_location, 190 *out_rollback_index); 191 if (ret != 0) { 192 printf("%s: init rollback index error\n", __FILE__); 193 return AVB_IO_RESULT_ERROR_IO; 194 } 195 ret = trusty_read_rollback_index(rollback_index_location, 196 out_rollback_index); 197 if (ret == 0) 198 return AVB_IO_RESULT_OK; 199 } else if (ret == 0) { 200 return AVB_IO_RESULT_OK; 201 } else { 202 printf("trusty_read_rollback_index ret = %x\n", ret); 203 return AVB_IO_RESULT_ERROR_IO; 204 } 205 #endif 206 } 207 return AVB_IO_RESULT_ERROR_IO; 208 } 209 210 static AvbIOResult write_rollback_index(AvbOps *ops, 211 size_t rollback_index_location, 212 uint64_t rollback_index) 213 { 214 #ifdef CONFIG_OPTEE_CLIENT 215 if (trusty_write_rollback_index(rollback_index_location, rollback_index)) { 216 printf("%s: Fail to write rollback index\n", __FILE__); 217 return AVB_IO_RESULT_ERROR_IO; 218 } 219 return AVB_IO_RESULT_OK; 220 #endif 221 return AVB_IO_RESULT_ERROR_IO; 222 } 223 224 static AvbIOResult read_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) 225 { 226 if (out_is_unlocked != NULL) { 227 #ifdef CONFIG_OPTEE_CLIENT 228 int ret; 229 230 ret = trusty_read_lock_state((uint8_t *)out_is_unlocked); 231 if (ret == TEE_ERROR_ITEM_NOT_FOUND) { 232 *out_is_unlocked = 1; 233 if (trusty_write_lock_state(*out_is_unlocked)) { 234 printf("%s: init lock state error\n", __FILE__); 235 return AVB_IO_RESULT_ERROR_IO; 236 } 237 238 ret = trusty_read_lock_state((uint8_t *)out_is_unlocked); 239 if(ret == 0) 240 return 0; 241 } else if (ret == 0) { 242 return AVB_IO_RESULT_OK; 243 } else { 244 printf("read_is_device_unlocked ret = %x\n", ret); 245 return AVB_IO_RESULT_ERROR_IO; 246 } 247 #endif 248 } 249 return AVB_IO_RESULT_ERROR_IO; 250 } 251 252 static AvbIOResult write_is_device_unlocked(AvbOps *ops, bool *out_is_unlocked) 253 { 254 if (out_is_unlocked != NULL) { 255 #ifdef CONFIG_OPTEE_CLIENT 256 if (trusty_write_lock_state(*out_is_unlocked)) { 257 printf("%s: Fail to write lock state\n", __FILE__); 258 return AVB_IO_RESULT_ERROR_IO; 259 } 260 return AVB_IO_RESULT_OK; 261 #endif 262 } 263 return AVB_IO_RESULT_ERROR_IO; 264 } 265 266 static AvbIOResult get_size_of_partition(AvbOps *ops, 267 const char *partition, 268 uint64_t *out_size_in_bytes) 269 { 270 struct blk_desc *dev_desc; 271 disk_partition_t part_info; 272 273 dev_desc = rockchip_get_bootdev(); 274 if (!dev_desc) { 275 printf("%s: Could not find device\n", __func__); 276 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 277 } 278 279 if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 280 printf("Could not find \"%s\" partition\n", partition); 281 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 282 } 283 *out_size_in_bytes = (part_info.size) * 512; 284 return AVB_IO_RESULT_OK; 285 } 286 287 static AvbIOResult get_unique_guid_for_partition(AvbOps *ops, 288 const char *partition, 289 char *guid_buf, 290 size_t guid_buf_size) 291 { 292 struct blk_desc *dev_desc; 293 disk_partition_t part_info; 294 dev_desc = rockchip_get_bootdev(); 295 if (!dev_desc) { 296 printf("%s: Could not find device\n", __func__); 297 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 298 } 299 300 if (part_get_info_by_name(dev_desc, partition, &part_info) < 0) { 301 printf("Could not find \"%s\" partition\n", partition); 302 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 303 } 304 if (guid_buf != NULL && guid_buf_size > 0) { 305 memcpy(guid_buf, part_info.uuid, guid_buf_size); 306 } 307 return AVB_IO_RESULT_OK; 308 } 309 310 /* read permanent attributes from rpmb */ 311 AvbIOResult avb_read_perm_attr(AvbAtxOps* atx_ops, 312 AvbAtxPermanentAttributes* attributes) 313 { 314 if (attributes != NULL) { 315 #ifdef CONFIG_OPTEE_CLIENT 316 trusty_read_permanent_attributes((uint8_t *)attributes, 317 sizeof(struct AvbAtxPermanentAttributes)); 318 return AVB_IO_RESULT_OK; 319 #endif 320 } 321 322 return -1; 323 } 324 325 /*read permanent attributes hash from efuse */ 326 AvbIOResult avb_read_perm_attr_hash(AvbAtxOps* atx_ops, 327 uint8_t hash[AVB_SHA256_DIGEST_SIZE]) 328 { 329 #ifdef CONFIG_OPTEE_CLIENT 330 if (trusty_read_attribute_hash((uint32_t *)hash, AVB_SHA256_DIGEST_SIZE / 4)) 331 return -1; 332 #else 333 avb_error("Please open the macro!\n"); 334 return -1; 335 #endif 336 return AVB_IO_RESULT_OK; 337 } 338 339 AvbOps* avb_ops_user_new(void) { 340 AvbOps* ops; 341 342 ops = calloc(1, sizeof(AvbOps)); 343 if (ops == NULL) { 344 avb_error("Error allocating memory for AvbOps.\n"); 345 goto out; 346 } 347 348 ops->ab_ops = calloc(1, sizeof(AvbABOps)); 349 if (ops->ab_ops == NULL) { 350 avb_error("Error allocating memory for AvbABOps.\n"); 351 free(ops); 352 goto out; 353 } 354 355 ops->atx_ops = calloc(1, sizeof(AvbAtxOps)); 356 if (ops->atx_ops == NULL) { 357 avb_error("Error allocating memory for AvbAtxOps.\n"); 358 free(ops->ab_ops); 359 free(ops); 360 goto out; 361 } 362 ops->ab_ops->ops = ops; 363 ops->atx_ops->ops = ops; 364 365 ops->read_from_partition = read_from_partition; 366 ops->write_to_partition = write_to_partition; 367 ops->validate_vbmeta_public_key = validate_vbmeta_public_key; 368 ops->read_rollback_index = read_rollback_index; 369 ops->write_rollback_index = write_rollback_index; 370 ops->read_is_device_unlocked = read_is_device_unlocked; 371 ops->write_is_device_unlocked = write_is_device_unlocked; 372 ops->get_unique_guid_for_partition = get_unique_guid_for_partition; 373 ops->get_size_of_partition = get_size_of_partition; 374 ops->ab_ops->read_ab_metadata = avb_ab_data_read; 375 ops->ab_ops->write_ab_metadata = avb_ab_data_write; 376 ops->atx_ops->read_permanent_attributes = avb_read_perm_attr; 377 ops->atx_ops->read_permanent_attributes_hash = avb_read_perm_attr_hash; 378 379 out: 380 return ops; 381 } 382 383 384 void avb_ops_user_free(AvbOps* ops) { 385 free(ops->ab_ops); 386 free(ops->atx_ops); 387 free(ops); 388 } 389