Index: boot/generic/include/gzip.h
===================================================================
--- boot/generic/include/gzip.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
+++ boot/generic/include/gzip.h	(revision 90f1f1988231da4facc94fa385270f4748b2e9cd)
@@ -30,6 +30,9 @@
 #define LIBCOMPRESS_GZIP_H_
 
+#include <stdbool.h>
 #include <stddef.h>
-size_t gzip_size(const void *, size_t);
+
+extern bool gzip_check(const void *, size_t);
+extern size_t gzip_size(const void *, size_t);
 extern int gzip_expand(const void *, size_t, void *, size_t);
 
Index: boot/generic/src/gzip.c
===================================================================
--- boot/generic/src/gzip.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
+++ boot/generic/src/gzip.c	(revision 90f1f1988231da4facc94fa385270f4748b2e9cd)
@@ -63,14 +63,22 @@
 } __attribute__((packed)) gzip_footer_t;
 
-size_t gzip_size(const void *src, size_t srclen)
+/** Check GZIP signature
+ *
+ * Checks whether the source buffer start with a GZIP signature.
+ *
+ * @param[in] src    Source data buffer.
+ * @param[in] srclen Source buffer size (bytes).
+ *
+ * @return True if GZIP signature found.
+ * @return False if no GZIP signature found.
+ *
+ */
+bool gzip_check(const void *src, size_t srclen)
 {
+	if ((srclen < (sizeof(gzip_header_t) + sizeof(gzip_footer_t))))
+		return false;
+
 	gzip_header_t header;
-	gzip_footer_t footer;
-
-	if ((srclen < sizeof(header)) || (srclen < sizeof(footer)))
-		return 0;
-
 	memcpy(&header, src, sizeof(header));
-	memcpy(&footer, src + srclen - sizeof(footer), sizeof(footer));
 
 	if ((header.id1 != GZIP_ID1) ||
@@ -78,5 +86,28 @@
 	    (header.method != GZIP_METHOD_DEFLATE) ||
 	    ((header.flags & (~GZIP_FLAGS_MASK)) != 0))
+		return false;
+
+	return true;
+}
+
+/** Get uncompressed size
+ *
+ * Note that the uncompressed size is read from the GZIP footer
+ * (and not calculated by acutally decompressing the GZip archive).
+ * Thus the source of the GZip archive needs to be trusted.
+ *
+ * @param[in]  src    Source data buffer.
+ * @param[out] srclen Source buffer size (bytes).
+ *
+ * @return Uncompressed size.
+ *
+ */
+size_t gzip_size(const void *src, size_t srclen)
+{
+	if (!gzip_check(src, srclen))
 		return 0;
+
+	gzip_footer_t footer;
+	memcpy(&footer, src + srclen - sizeof(footer), sizeof(footer));
 
 	return uint32_t_le2host(footer.size);
@@ -85,6 +116,6 @@
 /** Expand GZIP compressed data
  *
- * The routine allocates the output buffer based
- * on the size encoded in the input stream. This
+ * The routine compares the output buffer size with
+ * the size encoded in the input stream. This
  * effectively limits the size of the uncompressed
  * data to 4 GiB (expanding input streams that actually
@@ -108,20 +139,14 @@
 int gzip_expand(const void *src, size_t srclen, void *dest, size_t destlen)
 {
+	if (!gzip_check(src, srclen))
+		return EINVAL;
+
+	/* Decode header and footer */
+
 	gzip_header_t header;
+	memcpy(&header, src, sizeof(header));
+
 	gzip_footer_t footer;
-
-	if ((srclen < sizeof(header)) || (srclen < sizeof(footer)))
-		return EINVAL;
-
-	/* Decode header and footer */
-
-	memcpy(&header, src, sizeof(header));
 	memcpy(&footer, src + srclen - sizeof(footer), sizeof(footer));
-
-	if ((header.id1 != GZIP_ID1) ||
-	    (header.id2 != GZIP_ID2) ||
-	    (header.method != GZIP_METHOD_DEFLATE) ||
-	    ((header.flags & (~GZIP_FLAGS_MASK)) != 0))
-		return EINVAL;
 
 	if (destlen != uint32_t_le2host(footer.size))
Index: boot/generic/src/payload.c
===================================================================
--- boot/generic/src/payload.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
+++ boot/generic/src/payload.c	(revision 90f1f1988231da4facc94fa385270f4748b2e9cd)
@@ -61,12 +61,6 @@
 {
 	char *e = (char *) ext(s);
-	if (e != NULL && str_cmp(e, ".gz") == 0)
+	if ((e != NULL) && (str_cmp(e, ".gz") == 0))
 		*e = '\0';
-}
-
-static bool isgzip(const char *s)
-{
-	const char *e = ext(s);
-	return e != NULL && str_cmp(e, ".gz") == 0;
 }
 
@@ -82,17 +76,14 @@
 {
 	const char *name;
-	const uint8_t *data;
 	size_t packed_size;
-	size_t unpacked_size;
 
 	if (!tar_info(*cstart, cend, &name, &packed_size))
 		return false;
 
-	data = *cstart + TAR_BLOCK_SIZE;
+	const uint8_t *data = *cstart + TAR_BLOCK_SIZE;
 	*cstart += TAR_BLOCK_SIZE + ALIGN_UP(packed_size, TAR_BLOCK_SIZE);
 
-	bool gz = isgzip(name);
-
-	unpacked_size = gz ? gzip_size(data, packed_size) : packed_size;
+	bool gz = gzip_check(data, packed_size);
+	size_t unpacked_size = gz ? gzip_size(data, packed_size) : packed_size;
 
 	/* Components must be page-aligned. */
@@ -156,5 +147,5 @@
 	while (tar_info(start, payload_end, &name, &packed_size)) {
 		sz = ALIGN_UP(sz, PAGE_SIZE);
-		if (isgzip(name))
+		if (gzip_check(start + TAR_BLOCK_SIZE, packed_size))
 			sz += gzip_size(start + TAR_BLOCK_SIZE, packed_size);
 		else
