// SPDX-License-Identifier: GPL-2.0 #include #include #include #include "efistub.h" #include "inftrees.c" #include "inffast.c" #include "inflate.c" extern unsigned char _gzdata_start[], _gzdata_end[]; extern u32 __aligned(1) payload_size; static struct z_stream_s stream; efi_status_t efi_zboot_decompress_init(unsigned long *alloc_size) { efi_status_t status; int rc; /* skip the 10 byte header, assume no recorded filename */ stream.next_in = _gzdata_start + 10; stream.avail_in = _gzdata_end - stream.next_in; status = efi_allocate_pages(zlib_inflate_workspacesize(), (unsigned long *)&stream.workspace, ULONG_MAX); if (status != EFI_SUCCESS) return status; rc = zlib_inflateInit2(&stream, -MAX_WBITS); if (rc != Z_OK) { efi_err("failed to initialize GZIP decompressor: %d\n", rc); status = EFI_LOAD_ERROR; goto out; } *alloc_size = payload_size; return EFI_SUCCESS; out: efi_free(zlib_inflate_workspacesize(), (unsigned long)stream.workspace); return status; } efi_status_t efi_zboot_decompress(u8 *out, unsigned long outlen) { int rc; stream.next_out = out; stream.avail_out = outlen; rc = zlib_inflate(&stream, 0); zlib_inflateEnd(&stream); efi_free(zlib_inflate_workspacesize(), (unsigned long)stream.workspace); if (rc != Z_STREAM_END) { efi_err("GZIP decompression failed with status %d\n", rc); return EFI_LOAD_ERROR; } efi_cache_sync_image((unsigned long)out, outlen); return EFI_SUCCESS; }