void cavan_sha_finish(struct cavan_sha_context *context, u8 *digest) { u64 bits = context->count << 3; cavan_sha_update(context, "\x80", 1); if (context->remain > sizeof(context->buff) - sizeof(bits)) { mem_set(context->buff + context->remain, 0, sizeof(context->buff) - context->remain); context->transform(context->digest, context->dwbuff); mem_set(context->buff, 0, context->remain); } else { mem_set(context->buff + context->remain, 0, sizeof(context->buff) - context->remain - sizeof(bits)); } if (context->flags & SHA_FLAG_SWAP) { mem_copy_invert8(context->buff + sizeof(context->buff) - sizeof(bits), (void *) &bits, sizeof(bits)); } else { mem_copy(context->buff + sizeof(context->buff) - sizeof(bits), (void *) &bits, sizeof(bits)); } context->transform(context->digest, context->dwbuff); if (context->flags & SHA_FLAG_SWAP) { mem_swap32((u32 *) digest, context->digest, context->digest_size >> 2); } else {
int cavan_sha_update2(struct cavan_sha_context *context, int fd) { while (1) { ssize_t rdlen; char buff[4096]; rdlen = ffile_read(fd, buff, sizeof(buff)); if (rdlen <= 0) { return rdlen; } cavan_sha_update(context, buff, rdlen); } return 0; }
int bootimg_pack(struct bootimg_pack_option *option) { int fd; int ret; int image_count; struct bootimg_header hdr; struct bootimg_image images[4]; struct bootimg_image *p, *p_end; struct cavan_sha_context context; if (option->kernel == NULL || option->ramdisk == NULL) { pr_red_info("no kernel or ramdisk image specified"); return -EINVAL; } fd = open(option->output, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { pr_error_info("open file `%s' failed", option->output); return fd; } ret = lseek(fd, sizeof(hdr), SEEK_SET); if (ret < 0) { pr_red_info("cavan_file_seek_page_align"); goto out_close_fd; } cavan_sha1_context_init(&context); ret = cavan_sha_init(&context); if (ret < 0) { pr_red_info("cavan_sha_init"); goto out_close_fd; } memset(&hdr, 0, sizeof(hdr)); memcpy(hdr.magic, BOOT_MAGIC, sizeof(hdr.magic)); if (option->config) { ret = bootimg_parse_config_file(&hdr, option->config); if (ret < 0) { pr_red_info("bootimg_parse_config_file"); goto out_close_fd; } } else { memcpy(hdr.unused, option->unused, sizeof(hdr.unused)); hdr.page_size = option->page_size; hdr.kernel_addr = option->kernel_addr ?: option->base + option->kernel_offset; hdr.ramdisk_addr = option->ramdisk_addr ?: option->base + option->ramdisk_offset; hdr.second_addr = option->second_addr ?: option->base + option->second_offset; hdr.tags_addr = option->tags_addr ?: option->base + option->tags_offset; if (option->name) { strncpy((char *) hdr.name, option->name, sizeof(hdr.name)); } if (option->cmdline) { bootimg_copy_cmdline(&hdr, option->cmdline); } } images[0].name = option->kernel; images[0].size_addr = &hdr.kernel_size; images[1].name = option->ramdisk; images[1].size_addr = &hdr.ramdisk_size; images[2].name = option->second; images[2].size_addr = &hdr.second_size; image_count = 3; if (option->dt) { images[image_count].name = option->dt; images[image_count++].size_addr = &hdr.dt_size; } for (p = images, p_end = p + image_count; p < p_end; p++) { if (p->name) { println("write image %s", p->name); ret = bootimg_write_image(fd, p->name, p->size_addr, hdr.page_size, &context); if (ret < 0) { pr_red_info("bootimg_write_image"); goto out_close_fd; } } else { *p->size_addr = 0; } cavan_sha_update(&context, p->size_addr, sizeof(unsigned)); } if (option->remain) { println("write remain image %s", option->remain); ret = file_copy3(option->remain, fd); if (ret < 0) { pr_red_info("file_copy3"); goto out_close_fd; } } if (option->check_all) { cavan_sha_update(&context, &hdr.tags_addr, sizeof(hdr.tags_addr)); cavan_sha_update(&context, &hdr.page_size, sizeof(hdr.page_size)); cavan_sha_update(&context, hdr.unused, sizeof(hdr.unused)); cavan_sha_update(&context, hdr.name, sizeof(hdr.name)); cavan_sha_update(&context, hdr.cmdline, sizeof(hdr.cmdline)); if (hdr.extra_cmdline[0]) { cavan_sha_update(&context, hdr.extra_cmdline, sizeof(hdr.extra_cmdline)); } } cavan_sha_finish(&context, (u8 *) hdr.id); bootimg_header_dump(&hdr); ret = ffile_writeto(fd, &hdr, sizeof(hdr), 0); if (ret < 0) { pr_red_info("ffile_writeto"); goto out_close_fd; } pr_green_info("pack %s successfull", option->output); out_close_fd: close(fd); return ret; }