I've spent a couple of hour to figure out how the firmware update works in Canon DSLRs.
I've found a lot of stuff, SHA1, HMAC-SHA1, AES128 and of course the XOR decipher routines, but haven't got the whole picture.
I'm trying to summarize now what I've found, maybe somebody could continue the work or point me to the right direction.
I'm working with the 7D 1.1.0 firmware but I can port my stuff to other camera's firmware if it needed.
FF1543AC:
CERESJOB It is a jump table, I haven't found how and where this sub referenced.
if the job number is 29 then it jumps to
FF154E80:
UpdateFileData_CERES This sub loads the firmware file, deciphers the updater(s) and decrypts the fimrware payload.
After it called the FIO_OpenFile, and FIO_ReadFile calls the
DecryptoFir:
FF1C3D30:E92D4010 DecryptoFir STMFD SP!, {R4, LR} ; ===== SUB =====
FF1C3D34:E1A04000 MOV R4, R0 ; .fir start address
FF1C3D38:E5900024 LDR R0, [R0,#0x24] ; Updater1 header start
FF1C3D3C:E3500030 CMP R0, #0x30
FF1C3D40:0A000012 BEQ DecryptoFir_1
FF1C3D44:E59F1084 LDR R1, =0xAFCC ; dw_FF1C3DD0
FF1C3D48:E1A00004 MOV R0, R4
FF1C3D4C:EB043B6B BL sub_FF2D2B00
FF1C3D50:E3500000 CMP R0, #0
FF1C3D54:1A00000F BNE DecryptoFir_2
FF1C3D58:E59F1070 LDR R1, =0xAFCC ; dw_FF1C3DD0
FF1C3D5C:E1A00004 MOV R0, R4
FF1C3D60:EB043BAD BL sub_FF2D2C1C
FF1C3D64:E3500000 CMP R0, #0
FF1C3D68:1A00000A BNE DecryptoFir_2
FF1C3D6C:E1A00004 MOV R0, R4
FF1C3D70:EB043C02 BL UpdaterDecipher_caller
FF1C3D74:E3500000 CMP R0, #0
FF1C3D78:1A000006 BNE DecryptoFir_2
FF1C3D7C:E59F1050 LDR R1, =0xAFAC ; dw_FF1C3DD4
FF1C3D80:E1A00004 MOV R0, R4
FF1C3D84:EB043C85 BL FirmwareDecryptAndChecksum
FF1C3D88:E3500000 CMP R0, #0
FF1C3D8C:1A000001 BNE DecryptoFir_2
FF1C3D90:E3A00000 DecryptoFir_1 MOV R0, #0
FF1C3D94:E8BD8010 LDMFD SP!, {R4, PC}
-- ------------------------------------
FF1C3D98:E3E00000 DecryptoFir_2 MVN R0, #0 ; R0=FFFFFFFF, Error
FF1C3D9C:E8BD8010 LDMFD SP!, {R4, PC}
The two unknown subroutines (sub_FF2D2B00, sub_FF2D2C1C) do a lot of things (e.g. SHA1 hash calc)
The
UpdaterDecipher_caller deciphers the updater(s) using the well-known XOR tables.
FirmwareDecryptAndChecksum:
FF2D2FA0:E92D4010 FirmwareDecryptAndChecksum STMFD SP!, {R4, LR} ; ===== SUB =====
FF2D2FA4:E1A04000 MOV R4, R0 ; .fir start address
FF2D2FA8:E5900030 LDR R0, [R0,#0x30] ; Firmware start offset
FF2D2FAC:E7B02004 LDR R2, [R0,R4]!
FF2D2FB0:E0820000 ADD R0, R2, R0 ; Firmware start address
FF2D2FB4:E594202C LDR R2, [R4,#0x2C] ; Updater2 start offset
FF2D2FB8:EBFFFF83 BL FirmwareDecrypt
FF2D2FBC:E3700001 CMN R0, #1
FF2D2FC0:08BD8010 LDMEQFD SP!, {R4, PC}
FF2D2FC4:E3A00000 MOV R0, #0
FF2D2FC8:E5840020 STR R0, [R4,#0x20] ; Clear checksum
FF2D2FCC:E594C038 LDR R12, [R4,#0x38] ; Firmware file size
FF2D2FD0:E1A00004 MOV R0, R4
FF2D2FD4:E3A02000 MOV R2, #0
FF2D2FD8:E3A01000 MOV R1, #0
FF2D2FDC:E151000C FirmwareDecryptAndChecksum_1 CMP R1, R12
FF2D2FE0:34D03001 LDRCCB R3, [R0],#1
FF2D2FE4:32811001 ADDCC R1, R1, #1
FF2D2FE8:30832002 ADDCC R2, R3, R2 ; Calc checksum
FF2D2FEC:3AFFFFFA BCC FirmwareDecryptAndChecksum_1
FF2D2FF0:E1E00002 MVN R0, R2
FF2D2FF4:E5840020 STR R0, [R4,#0x20] ; Store checksum
FF2D2FF8:E3A00000 MOV R0, #0
FF2D2FFC:E8BD8010 LDMFD SP!, {R4, PC}
The FirmwareDecrypt has a lot of things: SHA1 calcs, and AES decrypt, but I can't follow that much subroutine calls.
I feel I'm close to it... I wrote a disassembler/debugger to work with the ARM binary (
see here) but it's not yet perfect (means I think it doesn't do that it should be to do).
Some important routines:
FF424CE0: AES_decrypt
FFFE00DC: HMAC-SHA1
FFFE10F4: SHA1_calculator
FF3DC280: SHA1_calc
FF37221C: XOR_decipher
For further check you can download the IDC file with these labels and comments from
here.
Dmit wrote:
"Firmware payload is encrypted by AES-128 in CTR mode. No SHA-256 is involved, only SHA-1 (which used twice to generate 256-bit value: 160 bits + 96 bits)"