path: root/utils/nwztools/upgtools/upg.h
diff options
Diffstat (limited to 'utils/nwztools/upgtools/upg.h')
1 files changed, 42 insertions, 16 deletions
diff --git a/utils/nwztools/upgtools/upg.h b/utils/nwztools/upgtools/upg.h
index bc7c9787c9..e6cdaba1f7 100644
--- a/utils/nwztools/upgtools/upg.h
+++ b/utils/nwztools/upgtools/upg.h
@@ -22,10 +22,9 @@
#define __UPG_H__
#include "misc.h"
-#include "fwp.h"
#include "mg.h"
-/** Firmware format
+/** Firmware format V1/V2
* The firmware starts with the MD5 hash of the entire file (except the MD5 hash
* itself of course). This is used to check that the file was not corrupted.
@@ -35,7 +34,20 @@
* the key and finding the right signature serves to authenticate the firmware.
* The header is followed by N entries (where N is the number of files) giving
* the offset, within the file, and size of each file. Note that the files in
- * the firmware have no name. */
+ * the firmware have no name. The only difference between V1 and V2 is that the
+ * size of the signature is 16 bytes instead of 8 and the upg entries are 16 bytes
+ * long so they are padded.
+ *
+ * There is, however a practical difference between how the OF performs the update on
+ * newer devices (and hence corrolates exactly with V2 usage). On these devices, the
+ * update script will first extract the first file (the bash script) and the second file
+ * which is called "md5.txt". At this point it then runs the script. Hence it is not
+ * important what the content of the second file is, it is not checked unless fwpup is
+ * called. For the records, here is an exerct of such a file:
+ * 838860800 eae2acabcd6523a750f61f5ea3e9a80b system.img
+ */
+#define NWZ_MD5_SIZE 16
struct upg_md5_t
@@ -44,7 +56,7 @@ struct upg_md5_t
struct upg_header_t
- uint8_t sig[NWZ_SIG_SIZE];
+ uint8_t sig[8];
uint32_t nr_files;
uint32_t pad; // make sure structure size is a multiple of 8
} __attribute__((packed));
@@ -55,6 +67,20 @@ struct upg_entry_t
uint32_t size;
} __attribute__((packed));
+struct upg_header_v2_t
+ uint8_t sig[16];
+ uint32_t nr_files;
+ uint32_t pad[3]; // make sure structure size is a multiple of 16
+} __attribute__((packed));
+struct upg_entry_v2_t
+ uint32_t offset;
+ uint32_t size;
+ uint32_t pad[2]; // make sure structure size is a multiple of 16
+} __attribute__((packed));
/** KAS / Key / Signature
* Since this is all very confusing, we need some terminology and notations:
@@ -131,7 +157,7 @@ struct nwz_model_t
* it is a KAS built from a key and sig brute-forced from an upgrade. In this
* case, the KAS might be different from the 'official' one although for all
* intent and purposes it should not make any difference. */
- char *kas;
+ const char *kas;
/* list of models with keys and status. Sentinel NULL entry at the end */
@@ -150,21 +176,21 @@ struct upg_file_t
struct upg_file_entry_t *files;
-/* decrypt a KAS into a key and signature, return <0 if the KAS contains a non-hex
- * character */
-int decrypt_keysig(const char kas[NWZ_KAS_SIZE], char key[NWZ_KEY_SIZE],
- char sig[NWZ_SIG_SIZE]);
-/* encrypt a key and signature into a KAS */
-void encrypt_keysig(char kas[NWZ_KEY_SIZE],
- const char key[NWZ_SIG_SIZE], const char sig[NWZ_KAS_SIZE]);
+/* IMPORTANT: all functions assume that the kas/key/sig are string and are zero terminated */
+/* Decrypt a KAS into a key and signature, return <0 if the KAS contains a non-hex
+ * character. The function will allocate key and sig if *key and/or *sig is NULL */
+int decrypt_keysig(const char *kas, char **key, char **sig);
+/* Encrypt a key and signature into a KAS, it will allocate kas if *kas is NULL */
+void encrypt_keysig(char **kas, const char *key, const char *sig);
/* Read a UPG file: return a structure on a success or NULL on error.
* Note that the memory buffer is modified to perform in-place decryption. */
-struct upg_file_t *upg_read_memory(void *file, size_t size, char key[NWZ_KEY_SIZE],
- char sig[NWZ_SIG_SIZE], void *u, generic_printf_t printf);
+struct upg_file_t *upg_read_memory(void *file, size_t size, const char *key,
+ const char *sig, void *u, generic_printf_t printf);
/* Write a UPG file: return a buffer containing the whole image, or NULL on error. */
-void *upg_write_memory(struct upg_file_t *file, char key[NWZ_KEY_SIZE],
- char sig[NWZ_SIG_SIZE], size_t *out_size, void *u, generic_printf_t printf);
+void *upg_write_memory(struct upg_file_t *file, const char *key,
+ const char *sig, size_t *out_size, void *u, generic_printf_t printf);
/* create empty upg file */
struct upg_file_t *upg_new(void);
/* append a file to a upg, data is NOT copied */