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 <nickfre...@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


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to