loader.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2017. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. *
  31. * The following software/firmware and/or related documentation ("MediaTek Software")
  32. * have been modified by MediaTek Inc. All revisions are subject to any receiver\'s
  33. * applicable license agreements with MediaTek Inc.
  34. */
  35. #include <pal_typedefs.h>
  36. #include <pal_log.h>
  37. #include <error.h>
  38. #include <img_info.h>
  39. #include <part_interface.h>
  40. #include <loader.h>
  41. #include <verified_boot_error.h>
  42. #include <string.h>
  43. #include <loader_util.h>
  44. /* load_addr and load_addr_high are used as default load address if load address value
  45. in image header is "refer to external setting" */
  46. uint32_t loader(struct img_load_config *img_load_config,
  47. struct img_info *img_info)
  48. {
  49. uint32_t ret = STATUS_OK;
  50. uint8_t *buf = (uint8_t *)get_vb_buf();
  51. uint32_t buf_sz = (uint32_t)get_vb_buf_sz();
  52. uint32_t found = 0;
  53. uint64_t offset = 0;
  54. uint32_t name_compare_len;
  55. uint32_t max_name_len;
  56. uint32_t retry = 0;
  57. ssize_t len = 0;
  58. if (NULL == buf)
  59. return ERR_VB_BUF_ADDR_INVALID;
  60. if (NULL == img_load_config)
  61. return ERR_VB_BUF_ADDR_INVALID;
  62. if (img_load_config->num_load_addr > MAX_NUM_IMG_WITH_ONE_HDR)
  63. return ERR_VB_BUF_OVERFLOW;
  64. if (MAX_HDR_SZ > buf_sz)
  65. return ERR_VB_BUF_OVERFLOW;
  66. memset(buf, 0x0, MAX_HDR_SZ);
  67. while (0 == found) {
  68. if (NULL == img_load_config->part_name) {
  69. ret = ERR_VB_NOT_VALID_STRING;
  70. break;
  71. }
  72. len = partition_read(img_load_config->part_name, offset, buf, MAX_HDR_SZ);
  73. if (len < 0) {
  74. ret = (uint32_t)len;
  75. break;
  76. }
  77. ret = get_img_info(buf, MAX_HDR_SZ, img_info);
  78. if (ret) {
  79. if (retry == 1) {
  80. /* retried but in vain */
  81. break;
  82. } else {
  83. /* there might be a rsa2048 signature here,
  84. retry with offset + rsa2048 sig size */
  85. offset += RSA2048_SIG_SZ;
  86. retry = 1;
  87. continue;
  88. }
  89. }
  90. /* reset retry flag since there might be multiple subimages in
  91. current partition and each of them may include rsa2048 signature */
  92. retry = 0;
  93. /* image name is not given, once valid image header is found,
  94. continue image loading */
  95. if (NULL == img_load_config->img_name) {
  96. found = 1;
  97. break;
  98. }
  99. name_compare_len = strlen(img_load_config->img_name);
  100. if (img_info->img_hdr_type == IMG_HDR_TYPE_RAW)
  101. max_name_len = MKIMG_NAME_SZ - 1;
  102. else if (img_info->img_hdr_type == IMG_HDR_TYPE_BOOT)
  103. max_name_len = BOOTIMG_NAME_SZ - 1;
  104. else {
  105. max_name_len = 0;
  106. ret = ERR_VB_INVALID_IMG_HDR;
  107. break;
  108. }
  109. if (name_compare_len > max_name_len) {
  110. ret = ERR_VB_NOT_VALID_STRING;
  111. break;
  112. }
  113. if (!memcmp(img_load_config->img_name, img_info->name, name_compare_len)) {
  114. found = 1;
  115. break;
  116. }
  117. offset += img_info->img_hdr_sz;
  118. offset += img_info->img_sz + ((((uint64_t)img_info->img_sz_high & 0xffffffff))
  119. << 32);
  120. }
  121. if (!found)
  122. ret = ERR_VB_IMG_NOT_FOUND;
  123. else {
  124. uint32_t vfy_en = 0;
  125. vfy_en = get_vfy_policy_by_name(img_load_config->part_name,
  126. img_load_config->img_name);
  127. if (vfy_en) {
  128. ret = vfy_phase1(img_load_config->part_name, offset, img_info);
  129. if (ret) {
  130. pal_log_err("vfy_phase1 failed(0x%x)\n", ret);
  131. return ret;
  132. }
  133. pal_log_err("vfy_phase1 ok\n");
  134. }
  135. /* load image */
  136. /* 64 bit loading address is not supported now */
  137. if (EXTERNAL_LOAD_ADDR == img_info->img_load_addr)
  138. img_info->img_load_addr = img_load_config->load_addr;
  139. if (TEE_LOAD_MODE == img_info->img_load_mode)
  140. img_info->img_load_addr = tee_get_load_addr(img_info->img_load_addr);
  141. /* load address range check */
  142. if (img_info->img_load_addr == 0) {
  143. ret = ERR_VB_INVALID_LOAD_ADDR;
  144. return ret;
  145. }
  146. len = partition_read(img_load_config->part_name, offset + img_info->img_hdr_sz,
  147. (uint8_t *)img_info->img_load_addr, img_info->img_dsz);
  148. if (len < 0) {
  149. ret = (uint32_t)len;
  150. return ret;
  151. }
  152. /* do padding */
  153. if (img_info->img_sz != img_info->img_dsz)
  154. memset((uint8_t *)img_info->img_load_addr + img_info->img_dsz, 0x0,
  155. (img_info->img_sz - img_info->img_dsz) * sizeof(uint8_t));
  156. if (vfy_en) {
  157. ret = vfy_phase2(img_info->img_load_addr, img_info->img_sz);
  158. if (ret) {
  159. pal_log_err("vfy_phase2 failed(0x%x)\n", ret);
  160. return ret;
  161. }
  162. pal_log_err("vfy_phase2 ok\n");
  163. }
  164. /* postprocessing */
  165. if (img_info->scrambled) {
  166. /* [TODO] restore */
  167. }
  168. }
  169. return ret;
  170. }