diff options
Diffstat (limited to 'utils/nwztools/upgtools/upg.h')
-rw-r--r-- | utils/nwztools/upgtools/upg.h | 58 |
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 */ |