WORK IN PROGRESS, NOT FINISHED YET! Ned to remake and update
- 1 getmkey utility
- 2 Printing hashes
- 3 Calculating hashes
- 4 Calculating and comparing hashes
- 5 Looking for dumps whose hashes are stored in a hash block file (CMAC):
- 6 Calculation of hash block (CMAC) for firmware modification
- 7 Save given key to binary file
- 8 Write calculated hash to file
- 9 mknewfs.sh
- 10 Other remarks
- 11 References
To calculate hashes you will need a 128-bit key which can be obtained from the TV or blu-ray player using getmkey utility. Check file getmkey/Makefile to get the idea how to build getmkey program, upload it to the TV or player and run it. If you do not wish to install a toolchain for cross-compilation, you may try prebuilt binaries: getmkey or getmkey_static.
If you have root access to the TV or player, run getmkey. You should get the output which looks like this:
opening /dev/mem ok! No key was supplied from a command line. Using mackey from /dev/tfsr11 Input key = 86d446c947765600a4a83098e6ee7ae2 After waiting 1 loops mkey='2b7e151628aed2a6abf7158809cf4f3c' # for BD-C6900 player #mkey='7ced26d8ca2fa0f80bc637e2ff07ec46' # B series #mkey='6f6bc7e1fc7f86bf9c150a82f343e2e0' # for T-VALDEUC-1014.3 TV ./chkhash -k 7ced26d8ca2fa0f80bc637e2ff07ec46 -h 3665940 rootfs.img
Last line of the output contains an mkey which will be used in chkhash program:
./chkhash -p offset n file : prints <n> hashes at <offset> in <file> offset less than zero means offset from the end of the file.
Example: print hashes in dumps from /dev/tbml9 and /dev/tbml10. Here and below we assume that dumps from firmware partitions /dev/tbmlX are stored in files tbmlX.bin, and dumps from /dev/stl0/X are stored in files stl0-X.bin.
./chkhash -p 0 6 tbml9.bin hash[ 0] = cb82e0476eecfe10b7415c099c34a53f length = 39735296 hash[ 1] = efb116822ffe713571b988f4bd71fb14 length = 36028416 hash[ 2] = 66d50c94a62cb51cf51482e77c74e267 length = 3104328 hash[ 3] = 1b8f9aa5846d4d8624482c183cb9c147 length = 4190228 hash[ 4] = 7bca4cf5f259475adac2c57965d7d6f1 length = 123510 Only 5 hashes were detected ./chkhash -p 0 6 tbml10.bin hash[ 0] = 25a3d13599932da3d255a749f1fe7581 length = 41050112 hash[ 1] = 2c23831d821407d180607890c07d4d22 length = 37797888 hash[ 2] = 60a8d999f3b6da20c58a3eb2056d43d6 length = 3104328 hash[ 3] = b0dac74b78a6814149187cf4d660f1f5 length = 4190228 hash[ 4] = 7bca4cf5f259475adac2c57965d7d6f1 length = 123510 Only 5 hashes were detected
Or print hash for /bin/authuld file (this hash is stored at the offset 4096 bytes from the end of RootFS image in /dev/tbml6 or /dev/tbml8):
./chkhash -p -4096 1 tbml6.bin hash[ 0] = 7fe99ddcf4c6c67f68374dbc60879f64 length = 36308 ./chkhash -p -4096 1 tbml8.bin hash[ 0] = 941137492edd0c83b489c665d6335295 length = 36308
./chkhash -k mkey -h length file : calculates and prints hash from the first <length> bytes of the file. if length is 0, the hash is calculated for full file length.
Example: if you have a copy of an authuld in current directory, run
./chkhash -k 2b7e151628aed2a6abf7158809cf4f3c -h 0 authuld Hash: 941137492edd0c83b489c665d6335295, length = 36308
Or you can calculate, for example a hash for bootloader (in /dev/tbml1):
./chkhash -k 2b7e151628aed2a6abf7158809cf4f3c -h 123510 tbml1.bin Hash: 7bca4cf5f259475adac2c57965d7d6f1, length = 123510
Calculating and comparing hashes
./chkhash -k mkey -m length file hash : calculates hash from the first <length> bytes of the file and compares with <hash> prints no result, useful in scripts only: return 0 if hashes are equal if length is 0, the hash is calculated for full file length.
Looking for dumps whose hashes are stored in a hash block file (CMAC):
./chkhash -k mkey -L offset n hashfile file1 file2 ... fileN : checks if <n> hashes stored at <offset> in a <hashfile> match : with hashes for <file1> <file2> ... <fileN>
Example: tbml10.bin (dump from /dev/tbml10), as shown above, contains a set of hashes for some files. Let's find these files (search will take some time because of calculation of hashes for many files):
./chkhash -k 2b7e151628aed2a6abf7158809cf4f3c -L 0 5 tbml10.bin tbml*.bin stl0-*.bin hash[ 0] = 25a3d13599932da3d255a749f1fe7581 length = 41050112 : stl0-16.bin hash[ 1] = 2c23831d821407d180607890c07d4d22 length = 37797888 : stl0-17.bin hash[ 2] = 60a8d999f3b6da20c58a3eb2056d43d6 length = 3104328 : tbml7.bin hash[ 3] = b0dac74b78a6814149187cf4d660f1f5 length = 4190228 : tbml8.bin hash[ 4] = 7bca4cf5f259475adac2c57965d7d6f1 length = 123510 : tbml1.bin
Here these files contain:
stl0-16.bin : mtd_exe stl0-17.bin : mtd_appdata tbml7.bin : kernel tbml8.bin : rootfs tbml1.bin : bootloader
Calculation of hash block (CMAC) for firmware modification
./chkhash -k mkey -H outfile file1 file2 ... fileN : creates hash block (cmac) for given input files
Hashes are written in the same order as supplied files. This can be used for building a hash block (CMAC) if you modify some firmware partitions.
Save given key to binary file
./chkhash -S key file : saves given hex <key> (16 byte) to binary <file> <file> is created if not existent and overwritten if already existent
./chkhash -S 6f6bc7e1fc7f86bf9c150a82f343e2e0 /mtd_rwcommon/test.bin
will create the file /mtd_rwcommon/test.bin with content (hex view): 00000000 6F 6B C7 E1 FC 7F 86 BF 9C 15 0A 82 F3 43 E2 E0 okÇáü.†¿œ..‚óCâà
Write calculated hash to file
./chkhash -k mkey -w offset k hashfile file : writes calculated hash for <file> (full length) at hash position <k> in a hash block located at <offset> in <hashfile> offset less than zero means offset from the end of the hashfile
./chkhash -k 6f6bc7e1fc7f86bf9c150a82f343e2e0 -w 0 0 /mtd_rwcommon/bml10.dmp /mtd_rwcommon/mtd_exe_part.dmp
will write the calculated hash of /mtd_rwcommon/mtd_exe_part.dmp ('_part' indicates that the dump is cut to the length read in /dev/bml0/10, for example using 'dd' to dump the first xx blocks only) in /mtd_rwcommon/bml10.dmp with no offset (0) and update the hash at index 0 (i.e. the hash of /mtd_exe)
This an example script to create a modified version of rootfs, mtd_exe or mtd_appdata. Please check it carefully before using. I did not test it for flashing my own firmware, so be careful. Read comments explaining the whole process and, anyway, you must accept any risk of possible bricking your TV or player.
Note that you will also need to know how to switch partitions for booting. Flashing of active (mounted) partition is dangerous, so you can only flash inactive (currently unused and unmounted) partition. So, first you will need to find which partition is active now. Run the following command in your device:
# df Filesystem 1k-blocks Used Available Use% Mounted on /dev/tbml8 2880 2880 0 100% / none 10240 20 10220 0% /dtv none 60204 0 60204 0% /core /dev/stl0/17 36928 36928 0 100% /mtd_appdata /dev/stl0/16 40128 40128 0 100% /mtd_exe
This is for BD-C6900 player. Other devices may have other filesystem structure, so procedure described here may be different. Here we can see that active devices are /dev/tbml8 /dev/stl0/17 /dev/stl0/16 which belong to second partiton and their CMAC data (hashes) are stored in /dev/tbml10. Therefore we can flash first partition: /dev/tbml6 /dev/stl0/15 /dev/stl0/14 and write their hashes to /dev/tbml9.
If we assume that dumps from firmware /dev/tbmlX are stored in files tbmlX.bin, and dumps from /dev/stl0/X are stored in files stl0-X.bin, first of all we need to copy currently active files to prepare them for first (now inactive) partition:
cp tbml8.bin tbml6.bin # rootfs cp stl0-17.bin stl0-15.bin # mtd_appdata cp stl0-16.bin stl0-14.bin # mtd_exe cp tbml7.bin tbml5.bin # kernel
Also, we need to copy hashes:
cp tbml10.bin tbml9.bin
Now we can start to modify the firmware: run
mknewfs.sh tbml6.bin tbml9.bin
for the first time to unsquash the rootfs. Then go to the tbml6.bin.rootdir and do necessary changes. Create new rootfs by running the same script again. You will get two files: tbml6.bin.new and tbml9.bin.new which contain new rootfs and new CMAC ready for flashing to /dev/tbml6 and /dev/tbml9. You may also modify mtd_exe by running
mknewfs.sh stl0-14.bin tbml9.bin
two times: first, to unsquash filesystem, and second time after your modifications to build new mtd_exe.
After flashing modified filesystems, kernel and hash block (CMAC), you will need to switch partitions to boot into your modified filesystems. That's it!
How to flash firmware partitions and switch them: this probably can be found elsewhere...
Note that I did not try that. So, consider this just as some theoretical analysis. Study it, check for possible errors, and use it on your own risk.
Download chkhash sources and precompiled getmkey chkhash-0.2.zip
Download precompiled chkhash for arm 
Download precompiled chkhash for win32 
Discussion on the SamyGO forum (can`t decide which subforum it belongs to...)