Canon EOS DSLR .FIR fomat
v1.1. September 4th, 2010 by Arm.Indy,
based on a first version by Trammell Hudson
- 550D/T2i update: the updater is now encrypted with AES like the payload, and new keys are used. The file format is the same.
Introduction
The following fir file format is used by Canon It is used to update code and data of EOS DSLRs, since the 1D Mark III.
The vocabulary used in this document (I.E. updater and firmware) is as used by Canon in their code. The purpose of releasing information about this file format is to allow running your own code on your camera and nothing else.
Mainly a FIR (for firmware) file contains all needed to update the camera: code that is run (updater) on the camera to do the updates and the updates themselves (called firmware).
Previous FIR file format
- 300D, 10D (fir v1)
- 1D, 1Ds, 1D Mark II, 1Ds MarkII, 1D Mark II n (.bin)
- 20D, 20Da, 350D. (fir v2)
- 5D, 30D, 400D. (fir v3). See [400d file format], by ASalina (April 28th, 2008)
- 40D, 50D, 450D, 500D, 1000D, 5D Mark II, WFT-E2, WFT-E3 (fir v4, DigicIII & Digic IV)
- 1D Mark III, 1Ds Mark III, 7D, 1D Mark IV (fir v4, with hmac signature)
- 550D (updater encrypted with AES, same format as 40D etc...)
Previous work
- Trammell Hudson (31Oct2009), firmware file update
- Dmit (24Sept2009), payload encryption
- emklap (11Mar2009), EOS 40D development discussion
- Tyra Misoux (Jan2009), Any developers interested in working on CHDK firmware for DSLRs ?
- emlkap (25Jul2008), This is how 40D (and 400D) code decrypth the flasher code 1(2) dissect_fw3_2.rar
- soldeersmurfje (20dec2007), 40D firmware decryption
References
- HMAC http://tools.ietf.org/html/rfc2104
- HMAC-SHA-1: http://tools.ietf.org/html/rfc2202
- SHA-1: http://tools.ietf.org/html/rfc3174
- MD5: http://tools.ietf.org/html/rfc1321
- AES: http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
- Block Cipher modes of operation: http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
FIR file format
Offset | Len | Description |
---|---|---|
0x00 | 0x10 |
Model Id (5D Mark II=0x8000218, 7D=0x8000250). Filled with 0. See Camera Model IDs from Phil Harvey ExifTool website: http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CanonModelID |
0x10 | 0x10 |
Version (ASCII string). "1.1.0". filled with 0. |
0x20 | 4 | File checksum (literally the sum of all the bytes) |
0x24 | 4 | 1st updater header offset (always 0xb0) |
0x28 | 4 | ciphered (xor) updater offset (always 0x120) |
0x2c | 4 | Offset of second updater header, only with dual Digic models.
5D has 0xffffffff, 7D has 0x001c0970. Setting this to 0xFFFFFFF or any other value causes orange box on 7D. this value is noted 'updater2' |
0x30 | 4 | firmware header offset. this value is noted 'firmware' |
0x34 | 4 | Length of payload (0xFFFFFFFF == until end of file?) |
0x38 | 4 | Length of FIR file in bytes |
0x3c | 4 | 0 |
0x40 | 4 | sha1 seed value. |
0x44 | 4 | used for signature (always here, only verified by dual Digic Models, only tested on 7D) |
0x5c | 4 | Flasher Header+Code length. Starts at 0xb0 |
0x64 | 4 | firmware Header + firmware data section length. Starts from value at 0x30 |
0x68 | 20 | flashers hmac-sha1 (hmac-sha1 is the final step) |
0x88 | 20 | firmware flasher hmac-sha1 (hmac-sha1 is the final step) |
0xb0 | 0x70 | updater1 header. Length of flasher program in bytes (orange box) |
0xb4 | 4 | Length of flasher program - 4 |
0xb8 | 4 | MBZ |
0xbc | 4 | IV for XOR decryptor. Used to compute initial offsets in 512/513 keys. (orange box) |
0x70 | 0xb0-0x120 is not zero when AES encryption is used. Like payload + 0xc... | |
0x120 | var | encrypted 1st updater. Soldeersmurfje discovered how to decode it and the 512/513 bytes tables in dec 2007. |
updater2 | 4 | second updater header (only with dual digic models). model Id |
updater2+0x10 | 4 | version (ascii) |
updater2+0x20 | 4 | checksum. seems a sum of bytes, but did not manage to compute it, argh!!! |
updater2+0x24 | 4 | 0xb0. relative offset, to updater header |
updater2+0x28 | 4 | 0x120. relative offset, to ciphered updater |
updater2+0x2c | 12 | 12 bytes = 0xff |
updater2+0x38 | 4 | updater length (including header) |
updater2+0xb0 | 4 | updater length |
updater2+0xbc | 4 | XOR deciphering seed |
updater2+0x120 | var | updater2 xor ciphered |
firmware | 4 | offset to decryption data = 0xc |
firmware+4 | 4 | offset to encrypted data = 0x7c. starts at 'firmware' offset |
firmware+8 | 4 | total firmware length (including header). starts at 'firmware' offset |
firmware+0xc | 4 | firmware length (encrypted part). starts at 'firmware' offset |
firmware+0x7c | var | encrypted firmware |
Sample headers
produced using fir_tool.py
- 1D Mark IV 1.0.8
See also http://magiclantern.wikia.com/wiki/Fir_Security
fileLen = 0xc4558c ---.fir header--- 0x000: modelId = 0x80000281, (1D Mark IV, DryOS) 0x010: version = 1.0.8 0x020: checksum = 0x9e3e4860 0x024: updater1 header = 0xb0 0x028: updater1 offset = 0x120 0x02c: updater2 offset = 0x1a3050 0x030: firmware offset = 0x211a40 0x034: 0xffffffff 0x038: embedded file size = 0xc4558c 0x03c: 0x0 0x040: sha1 seed = 0xbc4f9094 0x060: 0x211a40 0x064: firmware length = 0xa33b4c 0x068: updater1 hmac-sha1 = 0d316b779ac5d8b4845353801572e0177c15974a 0x088: firmware hmac-sha1 = c8212021525f2befe7bdefa43bb1f9d70606cdd3 ---updater1 header--- 0x0b0: updater1 length = 0x1a2f30. starts at 0x120 0x0b4: 0x1a2f2c 0x0b8: 0x0 0x0bc: xor seed value = 0xa698eb4 0x120: --- updater1 (ciphered) --- ---updater2 header--- 0x1a3050: (+0x000), modelId = 0x80000281, (1D Mark IV, DryOS) 0x1a3060: (+0x010), version = 1.0.8 0x1a3070: (+0x020), checksum? = 0xfd4e2681 0x1a3074: (+0x024), 0xb0 0x1a3078: (+0x028), 0x120 0x1a307c: (+0x02c), ffffffff ffffffff ffffffff 0x1a3088: (+0x038), updater length (including header) = 0x6e9f0. starts at 0x1a3050 0x1a3100: (+0x0b0), updater length = 0x6e8d0. starts at 0x1a3170 0x1a3104: (+0x0b4), 0x6e8c4 0x1a3108: (+0x0b8), 0x0 0x1a322c: (+0x0bc), xor seed value = 0xcd4ba73a 0x1a3170: (+0x120), --- updater2 (ciphered) --- ---firmware header--- 0x211a40: (+0x000), 0x211a44: (+0x004), offset to encrypted data = 0x7c. starts at 0x211a40 0x211a48: (+0x008), total firmware length (including header) = 0xa33b4c. starts at 0x211a40 - 0x211a4c: (+0x00c), firmware length (encrypted part) = 0xa33ad0. starts at 0x211abc ---firmware (encrypted)--- 0x211abc: (+0x07c)