[PATCH] tplink-safeloader: add optional extra header for support-list

Nick French nickfrench at gmail.com
Wed Aug 17 08:07:20 PDT 2022


Some TP-Link OEM firmwares add an extra len 0x18 header immediately
after the normal 0x8 byte parition header to support encrypted
partitions.

This extra header only applies to a subset of partitions.
For our purposes it only applies to the support-list partition.

The first 0x8 bytes are a flag to indicate if the contents are
encrypted or not, and the following 0x10 bytes form part of the
encryption key (used if flag is non-zero). Therefore an un-encrypted
parititon will have a zero-filled extra 0x18 bytes of header.

Add support to write this extra header for support-list partitions.

Note: currently only seen in the TP-Link Deco S4R v2, whose support
for factory images is only theoretical since all known OEM firmwares
require vendor-signed firmware updates, but that should not stop us
from generting valid factory images.

Signed-off-by: Nick French <nickfrench at gmail.com>
---
 src/tplink-safeloader.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/tplink-safeloader.c b/src/tplink-safeloader.c
index 7f9081d..babdea6 100644
--- a/src/tplink-safeloader.c
+++ b/src/tplink-safeloader.c
@@ -87,6 +87,7 @@ struct device_info {
 	const char *id;
 	const char *vendor;
 	const char *support_list;
+	uint32_t support_list_extra_header_len;
 	enum partition_trail_value part_trail;
 	struct {
 		enum soft_ver_type type;
@@ -1595,6 +1596,7 @@ static struct device_info boards[] = {
 			"{product_name:S4,product_ver:2.0.0,special_id:4A500000}\n"
 			"{product_name:S4,product_ver:2.0.0,special_id:41550000}\n"
 			"{product_name:S4,product_ver:2.0.0,special_id:4B520000}\n",
+		.support_list_extra_header_len = 0x18,
 		.part_trail = 0x00,
 		.soft_ver = SOFT_VER_DEFAULT,
 
@@ -3029,11 +3031,11 @@ static inline bool meta_partition_should_pad(enum partition_trail_value pv)
  * If the `data` pointer is NULL, then the required space is only allocated,
  * otherwise `data_len` bytes will be copied from `data` into the partition
  * entry. */
-static struct image_partition_entry init_meta_partition_entry(
+static struct image_partition_entry init_meta_partition_entry_with_extra_header(
 	const char *name, const void *data, uint32_t data_len,
-	enum partition_trail_value pad_value)
+	enum partition_trail_value pad_value, uint32_t extra_header_len)
 {
-	uint32_t total_len = sizeof(struct meta_header) + data_len;
+	uint32_t total_len = sizeof(struct meta_header) + extra_header_len + data_len;
 	if (meta_partition_should_pad(pad_value))
 		total_len += 1;
 
@@ -3049,8 +3051,10 @@ static struct image_partition_entry init_meta_partition_entry(
 	header->length = htonl(data_len);
 	header->zero = 0;
 
-	if (data)
-		memcpy(entry.data+sizeof(*header), data, data_len);
+	if (data) {
+		memset(entry.data+sizeof(*header),0,extra_header_len);
+		memcpy(entry.data+sizeof(*header)+extra_header_len, data, data_len);
+	}
 
 	if (meta_partition_should_pad(pad_value))
 		entry.data[total_len - 1] = (uint8_t) pad_value;
@@ -3058,6 +3062,14 @@ static struct image_partition_entry init_meta_partition_entry(
 	return entry;
 }
 
+static struct image_partition_entry init_meta_partition_entry(
+        const char *name, const void *data, uint32_t data_len,
+        enum partition_trail_value pad_value)
+{
+	static const uint32_t NO_EXTRA_HEADER = 0;
+	return init_meta_partition_entry_with_extra_header(name, data, data_len, pad_value, NO_EXTRA_HEADER);
+}
+
 /** Allocates a new image partition */
 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
 	struct image_partition_entry entry = {name, len, malloc(len)};
@@ -3191,8 +3203,9 @@ static struct image_partition_entry make_support_list(
 	const struct device_info *info)
 {
 	uint32_t len = strlen(info->support_list);
-	return init_meta_partition_entry(info->partition_names.support_list, info->support_list,
-		len, info->part_trail);
+
+	return init_meta_partition_entry_with_extra_header(info->partition_names.support_list, info->support_list,
+		len, info->part_trail, info->support_list_extra_header_len);
 }
 
 /** Partition with extra-para data */
-- 
2.37.1




More information about the openwrt-devel mailing list