1 /* 2 * (C) Copyright 2023 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <android_image.h> 9 #include <crypto.h> 10 #include <image.h> 11 #include <mp_boot.h> 12 #include <part.h> 13 #include <spl.h> 14 #include <asm/io.h> 15 16 #define BLK_CNT(_num_bytes, _block_size) \ 17 ((_num_bytes + _block_size - 1) / _block_size) 18 19 #ifdef CONFIG_ANDROID_BOOT_IMAGE 20 static int android_check_header(const struct andr_img_hdr *hdr) 21 { 22 return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE); 23 } 24 25 static void print_hash(const char *label, u8 *hash, int len) 26 { 27 int i; 28 29 printf("%s:\n 0x", label ? : "Hash"); 30 for (i = 0; i < len; i++) 31 printf("%02x", hash[i]); 32 printf("\n"); 33 } 34 35 #if 0 36 static void spl_android_print_contents(const struct andr_img_hdr *hdr) 37 { 38 const char * const p = IMAGE_INDENT_STRING; 39 /* os_version = ver << 11 | lvl */ 40 u32 os_ver = hdr->os_version >> 11; 41 u32 os_lvl = hdr->os_version & ((1U << 11) - 1); 42 u32 header_version = hdr->header_version; 43 44 printf("%skernel size: %x\n", p, hdr->kernel_size); 45 printf("%skernel address: %x\n", p, hdr->kernel_addr); 46 printf("%sramdisk size: %x\n", p, hdr->ramdisk_size); 47 printf("%sramdisk address: %x\n", p, hdr->ramdisk_addr); 48 printf("%ssecond size: %x\n", p, hdr->second_size); 49 printf("%ssecond address: %x\n", p, hdr->second_addr); 50 printf("%stags address: %x\n", p, hdr->tags_addr); 51 printf("%spage size: %x\n", p, hdr->page_size); 52 printf("%sheader_version: %x\n", p, header_version); 53 /* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C) 54 * lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M) */ 55 printf("%sos_version: %x (ver: %u.%u.%u, level: %u.%u)\n", 56 p, hdr->os_version, 57 (os_ver >> 7) & 0x7F, (os_ver >> 14) & 0x7F, os_ver & 0x7F, 58 (os_lvl >> 4) + 2000, os_lvl & 0x0F); 59 printf("%sname: %s\n", p, hdr->name); 60 printf("%scmdline: %s\n", p, hdr->cmdline); 61 62 if (header_version == 1 || header_version == 2) { 63 printf("%srecovery dtbo size: %x\n", p, hdr->recovery_dtbo_size); 64 printf("%srecovery dtbo offset: %llx\n", p, hdr->recovery_dtbo_offset); 65 printf("%sheader size: %x\n", p, hdr->header_size); 66 } 67 68 if (header_version == 2 || header_version == 3) { 69 printf("%sdtb size: %x\n", p, hdr->dtb_size); 70 printf("%sdtb addr: %llx\n", p, hdr->dtb_addr); 71 } 72 73 if (header_version >= 3) { 74 printf("%scmdline: %s\n", p, hdr->total_cmdline); 75 printf("%svendor ramdisk size: %x\n", p, hdr->vendor_ramdisk_size); 76 printf("%svendor page size: %x\n", p, hdr->vendor_page_size); 77 printf("%svendor header version: %d\n", p, hdr->vendor_header_version); 78 printf("%svendor header size: %x\n", p, hdr->vendor_header_size); 79 } 80 81 if (header_version >= 4) { 82 printf("%svendor ramdisk table size: %x\n", 83 p, hdr->vendor_ramdisk_table_size); 84 printf("%svendor ramdisk table entry num: %x\n", 85 p, hdr->vendor_ramdisk_table_entry_num); 86 printf("%svendor ramdisk table entry size: %x\n", 87 p, hdr->vendor_ramdisk_table_entry_size); 88 printf("%svendor bootconfig size: %d\n", 89 p, hdr->vendor_bootconfig_size); 90 } 91 } 92 #endif 93 94 static ulong android_size(struct andr_img_hdr *hdr) 95 { 96 ulong len; 97 98 len = hdr->page_size + 99 ALIGN(hdr->kernel_size, hdr->page_size) + 100 ALIGN(hdr->ramdisk_size, hdr->page_size) + 101 ALIGN(hdr->second_size, hdr->page_size); 102 if (hdr->header_version > 0) 103 len += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); 104 if (hdr->header_version > 1) 105 len += ALIGN(hdr->dtb_size, hdr->page_size); 106 #if 0 107 spl_android_print_contents(hdr); 108 #endif 109 110 return len; 111 } 112 113 int spl_load_android(struct task_data *data) 114 { 115 struct spl_load_info *info = &data->info; 116 void *buf = (void *)CONFIG_SPL_BOOT_IMAGE_BUF; 117 disk_partition_t part; 118 ulong blkcnt; 119 120 debug("== Android: load start\n"); 121 122 if (part_get_info_by_name(info->dev, "boot", &part) < 0) { 123 printf("No boot partition\n"); 124 return -ENOENT; 125 } 126 127 blkcnt = BLK_CNT(sizeof(struct andr_img_hdr), info->bl_len); 128 if (info->read(info, part.start, blkcnt, buf) != blkcnt) 129 return -EIO; 130 131 if (android_check_header(buf)) 132 return -EINVAL; 133 134 blkcnt = BLK_CNT(android_size(buf), info->bl_len); 135 if (info->read(info, part.start, blkcnt, buf) != blkcnt) 136 return -EIO; 137 138 data->boot_addr = (void *)CONFIG_SPL_BOOT_IMAGE_BUF; 139 data->boot_size = blkcnt * info->bl_len; 140 141 flush_dcache_range((ulong)data, (ulong)data + sizeof(*data)); 142 flush_dcache_range((ulong)buf, (ulong)buf + blkcnt); 143 144 debug("== Android: load 0x%08lx size OK\n", blkcnt * info->bl_len); 145 146 return 0; 147 } 148 149 #ifdef CONFIG_ARMV8_CE_SHA1 150 int spl_hash_android(struct task_data *data) 151 { 152 struct andr_img_hdr *hdr = (void *)CONFIG_SPL_BOOT_IMAGE_BUF; 153 sha1_context ctx; 154 uchar hash[32]; 155 void *buf; 156 157 printf("== Android: hash start\n"); 158 159 if (hdr->header_version >= 3) 160 return -EINVAL; 161 162 sha1_starts(&ctx); 163 164 buf = (void *)hdr + hdr->page_size; 165 sha1_update(&ctx, (const uchar *)buf, hdr->kernel_size); 166 sha1_update(&ctx, (const uchar *)&hdr->kernel_size, sizeof(hdr->kernel_size)); 167 168 buf += ALIGN(hdr->kernel_size, hdr->page_size); 169 sha1_update(&ctx, (const uchar *)buf, hdr->ramdisk_size); 170 sha1_update(&ctx, (const uchar *)&hdr->ramdisk_size, sizeof(hdr->ramdisk_size)); 171 172 buf += ALIGN(hdr->ramdisk_size, hdr->page_size); 173 sha1_update(&ctx, (const uchar *)buf, hdr->second_size); 174 sha1_update(&ctx, (const uchar *)&hdr->second_size, sizeof(hdr->second_size)); 175 176 if (hdr->header_version > 0) { 177 buf += ALIGN(hdr->second_size, hdr->page_size); 178 sha1_update(&ctx, (const uchar *)buf, hdr->recovery_dtbo_size); 179 sha1_update(&ctx, (const uchar *)&hdr->recovery_dtbo_size, sizeof(hdr->recovery_dtbo_size)); 180 } 181 if (hdr->header_version > 1) { 182 buf += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); 183 sha1_update(&ctx, (const uchar *)buf, hdr->dtb_size); 184 sha1_update(&ctx, (const uchar *)&hdr->dtb_size, sizeof(hdr->dtb_size)); 185 } 186 187 sha1_finish(&ctx, hash); 188 189 if (memcmp(hash, hdr->id, 20)) { 190 print_hash("Hash from header", (u8 *)hdr->id, 20); 191 print_hash("Hash real", (u8 *)hash, 20); 192 return -EBADFD; 193 } 194 195 printf("== Android: hash OK, 0x%08lx\n", (ulong)data->boot_addr); 196 197 return 0; 198 } 199 200 #else 201 int spl_hash_android(struct task_data *data) 202 { 203 struct andr_img_hdr *hdr = (void *)CONFIG_SPL_BOOT_IMAGE_BUF; 204 struct udevice *dev; 205 sha_context ctx; 206 uchar hash[32]; 207 void *buf; 208 209 debug("== Android: hash start\n"); 210 211 if (hdr->header_version >= 3) 212 return -EINVAL; 213 214 ctx.algo = CRYPTO_SHA1; 215 dev = crypto_get_device(ctx.algo); 216 if (!dev) { 217 printf("No crypto device for sha1\n"); 218 return -ENODEV; 219 } 220 221 ctx.length = hdr->kernel_size + sizeof(hdr->kernel_size) + 222 hdr->ramdisk_size + sizeof(hdr->ramdisk_size) + 223 hdr->second_size + sizeof(hdr->second_size); 224 if (hdr->header_version > 0) 225 ctx.length += hdr->recovery_dtbo_size + sizeof(hdr->recovery_dtbo_size); 226 if (hdr->header_version > 1) 227 ctx.length += hdr->dtb_size + sizeof(hdr->dtb_size); 228 229 crypto_sha_init(dev, &ctx); 230 231 buf = (void *)hdr + hdr->page_size; 232 crypto_sha_update(dev, buf, hdr->kernel_size); 233 crypto_sha_update(dev, &hdr->kernel_size, sizeof(hdr->kernel_size)); 234 235 buf += ALIGN(hdr->kernel_size, hdr->page_size); 236 crypto_sha_update(dev, buf, hdr->ramdisk_size); 237 crypto_sha_update(dev, &hdr->ramdisk_size, sizeof(hdr->ramdisk_size)); 238 239 buf += ALIGN(hdr->ramdisk_size, hdr->page_size); 240 crypto_sha_update(dev, buf, hdr->second_size); 241 crypto_sha_update(dev, &hdr->second_size, sizeof(hdr->second_size)); 242 243 if (hdr->header_version > 0) { 244 buf += ALIGN(hdr->second_size, hdr->page_size); 245 crypto_sha_update(dev, buf, hdr->recovery_dtbo_size); 246 crypto_sha_update(dev, &hdr->recovery_dtbo_size, sizeof(hdr->recovery_dtbo_size)); 247 } 248 if (hdr->header_version > 1) { 249 buf += ALIGN(hdr->recovery_dtbo_size, hdr->page_size); 250 crypto_sha_update(dev, buf, hdr->dtb_size); 251 crypto_sha_update(dev, &hdr->dtb_size, sizeof(hdr->dtb_size)); 252 } 253 254 crypto_sha_final(dev, &ctx, hash); 255 256 if (memcmp(hash, hdr->id, 20)) { 257 print_hash("Hash from header", (u8 *)hdr->id, 20); 258 print_hash("Hash real", (u8 *)hash, 20); 259 return -EBADFD; 260 } 261 262 debug("== Android: hash OK, 0x%08lx\n", (ulong)data->boot_addr); 263 264 return 0; 265 } 266 267 #endif 268 #endif 269 270 #ifdef CONFIG_ROCKCHIP_FIT_IMAGE 271 int spl_load_fit(struct task_data *data) 272 { 273 struct spl_load_info *info = &data->info; 274 void *buf = (void *)CONFIG_SPL_BOOT_IMAGE_BUF; 275 disk_partition_t part; 276 ulong blkcnt; 277 int size; 278 279 debug("== FIT: load start\n"); 280 281 if (part_get_info_by_name(info->dev, "boot", &part) < 0) { 282 printf("No boot partition\n"); 283 return -ENOENT; 284 } 285 286 blkcnt = BLK_CNT(sizeof(struct fdt_header), info->bl_len); 287 if (info->read(info, part.start, blkcnt, buf) != blkcnt) 288 return -EIO; 289 290 if (fdt_check_header(buf)) 291 return -EINVAL; 292 293 size = fit_get_totalsize(buf, &size); 294 blkcnt = BLK_CNT(size, info->bl_len); 295 if (info->read(info, part.start, blkcnt, buf) != blkcnt) 296 return -EIO; 297 298 flush_dcache_range((ulong)buf, (ulong)buf + blkcnt); 299 300 debug("== FIT: load 0x%08x size OK\n", size); 301 302 return 0; 303 } 304 #endif 305 306