collected: shiny new update keys for 1.2.4
some background on how the update works
On startup the shine checks the external sdcard for some special files. If there is a file named update.zip, the system starts with /dev/block/mmcblk0p4 mounted as filesystem root – and /sbin/recovery is executed.
You can find the code that forms that little binary here.
_note: in the head section of recovery.cpp you can find a short outline on how update „notification“ works
First recovery checks the cryptographic signature of the update.zip by
- reading the public keys (yes, plural is possible – see load_keys in verifier.cpp) from /res/keys (stored in the recovery partition),
- creating the hash over the update.zip,
- extracting the signature embedded in the comment section,
- decrypt hash by using the public keys from /res/keys and
- compare own hash with hash from the signature.
After a successful verification of the update.zip the zip-container itself is opened and recovery checks for /META-INF/com/google/android/update-binary and – if it is present – executes it. The binary then starts running the script stored in /META-INF/com/google/android/updater-script that performs the installation steps. The script itself is written in edify – see here for a short overview.
_note: for hunting bugs during the update process cat /tmp/recovery.log
replace the key – old version / pre 1.2.4
Currently only the public key used by the Telekom is stored in the /res/keys-file. So only the owner of the private key – the Telekom – can create valid update-files (by signing them).
By replacing the public key in the shine by using the well-known testing key contained in the android sources everyone can create valid update files (and of course – you can re-sign the public update from the Telekom to use them too – if you want).
_note: you can find the keys here
First you must convert the key to the format the recovery expects. This is done by using the tool dumpkey – you can find the source here.
java -jar dumpkey.jar testkey.x509.pem > testkey.x509.c
gives you
{64,0xc926ad21,{1795090719,2141396315,950055447,-1713398866,-26044131,1920809988,546586521,-795969498,1776797858,-554906482,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,-1731647369,323993566,28517732,609753416,1826472888,215237850,-33324596,-245884705,-1066504894,774857746,154822455,-1797768399,-1536767878,-1275951968,-1500189652,87251430,-1760039318,120774784,571297800,-599067824,-1815042109,-483341846,-893134306,-1900097649,-1027721089,950095497,555058928,414729973,1136544882,-1250377212,465547824,-236820568,-1563171242,1689838846,-404210357,1048029507,895090649,247140249,178744550,-747082073,-1129788053,109881576,-350362881,1044303212,-522594267,-1309816990,-557446364,-695002876},{-857949815,-510492167,-1494742324,-1208744608,251333580,2131931323,512774938,325948880,-1637480859,2102694287,-474399070,792812816,1026422502,2053275343,-1494078096,-1181380486,165549746,-21447327,-229719404,1902789247,772932719,-353118870,-642223187,216871947,-1130566647,1942378755,-298201445,1055777370,964047799,629391717,-2062222979,-384408304,191868569,-1536083459,-612150544,-1297252564,-1592438046,-724266841,-518093464,-370899750,-739277751,-1536141862,1323144535,61311905,1997411085,376844204,213777604,-217643712,9135381,1625809335,-1490225159,-1342673351,1117190829,-57654514,1825108855,-1281819325,1111251351,-1726129724,1684324211,-1773988491,367251975,810756730,-1941182952,1175080310}}
If your shine is already rooted, use your ADB shell and do the following:
# cd /mnt/sdcard
# mkdir mnt_recovery
# mount -t ext2 /dev/block/mmcblk0p4 mnt_recovery
# busybox cp mnt_recovery/res/keys mnt_recovery/res/keys.bck
# cat << 'EOF' > mnt_recovery/res/keys
{64,0xc926ad21,{1795090719,2141396315,950055447,-1713398866,-26044131,1920809988,546586521,-795969498,1776797858,-554906482,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,-1731647369,323993566,28517732,609753416,1826472888,215237850,-33324596,-245884705,-1066504894,774857746,154822455,-1797768399,-1536767878,-1275951968,-1500189652,87251430,-1760039318,120774784,571297800,-599067824,-1815042109,-483341846,-893134306,-1900097649,-1027721089,950095497,555058928,414729973,1136544882,-1250377212,465547824,-236820568,-1563171242,1689838846,-404210357,1048029507,895090649,247140249,178744550,-747082073,-1129788053,109881576,-350362881,1044303212,-522594267,-1309816990,-557446364,-695002876},{-857949815,-510492167,-1494742324,-1208744608,251333580,2131931323,512774938,325948880,-1637480859,2102694287,-474399070,792812816,1026422502,2053275343,-1494078096,-1181380486,165549746,-21447327,-229719404,1902789247,772932719,-353118870,-642223187,216871947,-1130566647,1942378755,-298201445,1055777370,964047799,629391717,-2062222979,-384408304,191868569,-1536083459,-612150544,-1297252564,-1592438046,-724266841,-518093464,-370899750,-739277751,-1536141862,1323144535,61311905,1997411085,376844204,213777604,-217643712,9135381,1625809335,-1490225159,-1342673351,1117190829,-57654514,1825108855,-1281819325,1111251351,-1726129724,1684324211,-1773988491,367251975,810756730,-1941182952,1175080310}}
EOF
# sync
Of course – you can also add the testkey to the key already contained in the key file. Just run step 5 in the following color:
cat << 'EOF' >> mnt_recovery/res/keys
, {64,0xc926ad21,{1795090719,2141396315,950055447,-1713398866,-26044131,1920809988,546586521,-795969498,1776797858,-554906482,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,-1731647369,323993566,28517732,609753416,1826472888,215237850,-33324596,-245884705,-1066504894,774857746,154822455,-1797768399,-1536767878,-1275951968,-1500189652,87251430,-1760039318,120774784,571297800,-599067824,-1815042109,-483341846,-893134306,-1900097649,-1027721089,950095497,555058928,414729973,1136544882,-1250377212,465547824,-236820568,-1563171242,1689838846,-404210357,1048029507,895090649,247140249,178744550,-747082073,-1129788053,109881576,-350362881,1044303212,-522594267,-1309816990,-557446364,-695002876},{-857949815,-510492167,-1494742324,-1208744608,251333580,2131931323,512774938,325948880,-1637480859,2102694287,-474399070,792812816,1026422502,2053275343,-1494078096,-1181380486,165549746,-21447327,-229719404,1902789247,772932719,-353118870,-642223187,216871947,-1130566647,1942378755,-298201445,1055777370,964047799,629391717,-2062222979,-384408304,191868569,-1536083459,-612150544,-1297252564,-1592438046,-724266841,-518093464,-370899750,-739277751,-1536141862,1323144535,61311905,1997411085,376844204,213777604,-217643712,9135381,1625809335,-1490225159,-1342673351,1117190829,-57654514,1825108855,-1281819325,1111251351,-1726129724,1684324211,-1773988491,367251975,810756730,-1941182952,1175080310}}
EOF
Note the comma surrounded by TWO spaces (SPACEKOMMASPACE) in front of the key (and the >> instead of > to append data). If you keep the Telekom key inside of the key-file you can install Telekom update-files without doing anything (but that contains the risk that the big magenta just kicks out the testkey – and locks the device finally).
_note: if you accidentally whipped out the Telekom key (as I did) – here is a backup:
{64,0x43e8c79d,{3676113227,1369749849,185223027,4193363093,2748936052,3982115949,2510941709,3179856730,3334762442,877424379,1572534478,379110109,3828184589,896326794,3259452337,1537333391,1527246812,1948881733,2695224641,3229564848,935338986,1880890185,1109044213,3584680280,2980215301,1048464167,1625211812,3380609409,1325015002,3048088550,3309007604,856748852,2742900622,1536007600,534693848,362616682,1757112249,1124497581,2589504072,3233109600,1483976042,1367799680,3874016522,3186374915,314458865,2533711827,917955710,2798363551,1533164771,21896696,577058097,4118697084,2950684889,1199785220,896256126,2013061576,3648332184,512726633,3829734369,3492448310,1658713944,2502792484,2381120692,2638223166},{2804200884,415193597,2952297320,1796440253,3760790861,2358398962,1319099071,1797194474,3920925071,3251309220,3091529551,3449146706,501734315,1726066195,2560662010,922451496,3625301210,3511962485,3446896765,2852859028,3995066542,3771896184,1498517695,1518271224,2813835315,2438495713,4214917633,1229593951,2879391816,2953200436,49762796,702148507,896186987,2106390057,3257996684,2916017064,2570034595,545791097,3544317144,1467421123,2340085279,3793830820,1463904638,2299616657,16368580,1993463273,20991070,1752616193,1008234173,2481181795,2499980873,904917164,906206298,2700276043,1728187988,1246428162,2078812943,732584325,881425958,3846779747,1384713822,2197399727,1513320059,731791506}}
If your shine is not rooted yet (and the serial number is below 20311241 – and you have not installed the update 1.2.4) you can just download the recovery.img.fixed_initrd_and_testkey, put it on a sdcard (!!!DO NOT FORGET TO RENAME IT TO recovery.img!!!) and restart your shine. On boot the shine starts to install the image in the background – so just wait (do nothing) till the reader goes down. Power it on again and your shine has ADB access and the testkey installed.
To sign an update.zip just run
java -jar signapk.jar -w testkey.x509.pem testkey.pk8 update.zip update_signed.zip
Then copy the update_signed.zip to your sdcard (and rename it to update.zip).
Example: update zip that just replaces the startup logo of the shine…
Intermezzo: The startup logo
The system/bin/upgrade.sh tells us that the logo lives in /dev/block/mmcblk0@18432 (bs=512). The name suggest that the image uses a 4 bit raw format – native resolution of the display is 1024×758 (makes 388096 bytes).
To prove that, I did a quick
dd if=/dev/block/mmcblk0 bs=1 skip=9437184 count=388096 of=raw_logo
Moved the file to my desktop and fired
cat raw_logo.org | convert -depth 4 -size 1024x758+0 gray:- pic.png
on it. Result:
_note: convert is part of imagemagic
After changing the image recreate the 4-bit-grayscale image with
convert logo_rework.png -size 1024x758+0 -depth 4 logo_rework.gray
Now write the raw image back to the shine using dd again:
dd if=logo_rework.gray of=/dev/block/mmcblk0 bs=1 seek=9437184
Reboot and enjoy your new startup logo!
back to the update example…
It just contains a short example of the META-INF/com/google/android/updater-script that invokes a one-liner shell script – nothing more.
ui_print("!!! this is only a demo !!!");
show_progress(0.05, 2);
assert(getprop("ro.product.device") == "imx50_rdp" || getprop("ro.build.product") == "imx50_rdp");
ui_print("Target device check: ok");
ui_print("use it for something usefull...");
show_progress(0.45, 90);
package_extract_file("install_logo.sh", "/tmp/install_logo.sh");
package_extract_file("logo.raw", "/tmp/logo.raw");
set_perm(0, 0, 0755, "/tmp/install_logo.sh");
set_perm(0, 0, 0555, "/tmp/logo.raw");
run_program("/tmp/install_logo.sh");
_note: never forget the empty newline at the end of the edify scripts!
_note: never forget to set proper permissions for your shell scripts!!
_note: never forget to add the bash bang on top of your shell scripts!!!
important_note: after installing 1.2.4 the shine reports itself as imx50_rdp_2 – so the above example must be adapted!!!
This update can be used to check if the testkey is installed.
the 1.2.4 update
I used the ability to sign my own update-packages to rework the latest update for the old shine. A rough overview of what I have done:
- add android testkey to all /res/keys
- add ADB on startup (hardcoded in upgrade_check.sh, /system/bin/adb)
- add su (/system/bin/su)
- fixes wrong waveform-target in upgrade_check.sh
- adds user_script.sh-hook in upgrade_check.sh
- re-enables recovery.img-hook in upgrade_check.sh
- add links to some tools (no need to write busybox in front of every important command)
- enable ADB in recovery
- added imx50_rdp_2 in the target test of the updater-script („big update“ can be installed over and over)
I used the update downloaded from Hugendubel. See the repack_and_sign.sh script in the downloads to get an idea on how it is done (trust me – its easy). To proceed for your own, just
- unpack the update.zip
- unpack the orig_update inside the update to orig_update
- replace META-INF/com/google/android/updater-script in update and orig_update by the ones used in the provided reworked
- replace all /res/keys-files to add testkey
- change the default.prop (secure = 0; debug=1, adb = 1)
- replace all upgrade_check.sh by provided one
- run pack_and_sign.sh…
_note: Watch the asserts inside of the updater-script. If they catch in the updater may tell misleading error messages. Just add verbose debug! And as noted above: have an eye to cat /tmp/recovery.log…
_note: tested by starting on a shine with 1.0.1 (rooted), installed recovery that brings the testkeys, than loaded the reworked 1.2.4 update…
the dead end – waveform.bin
Together with frank-w from the lesen.net-forum we discussed an upgrade-way over the waveform cause it is also written by upgrade_check.sh – without any checks:
...
elif [ -e /mnt/sdcard/extsd/waveform.bin ]; then
echo "---> Programming waveform ----------------------------------------"
busybox dd if=/mnt/sdcard/extsd/waveform.bin of=/dev/mmcblk0 bs=512 seek=14336
sync
...
Since the waveform binary is located in front of /mmcblk0p1 („MEIN TOLINO“) and – even more important – /mmcblk0p2 aka /system we had the idea to overwrite these two partitions by offering a waveform image that contains these parts. It sounded promising and worked on the console (directly on the shine – just dd the waveform + partition image). But on startup – the upgrade_check catches in and starts writing – the shine goes mad and killed all processes cause he runs out of memory… strange. But then, ohhhhh, that hurts so much: the actual device on the shine lives in /dev/block/mmcblk0 – but the upgrade_check writes to /dev/mmcblk0. And that is mounted via tmpfs. So on start – while writing to the NEW file /dev/mmcblk0 dd eats all the memory. Nice bug. Or was that intentional, Mr. big magenta? Huh?
left overs…
The process of changing the keys / building updates etc was not really straight forward. It took some hours of testing… here are some snippets that turned out to be useful…
If you wanna change the /system – remount rw:
mount -o remount,rw /dev/block/mmcblk0p2 /system
The su binary needs the set u-id permissions:
chmod 6555 /system/bin/su
Script that adds the testkeys in /mmcblk0p4/res/keys (recovery partition):
#!/system/bin/bash
mkdir /mnt/sdcard/recovery
mount -t ext2 /dev/block/mmcblk0p4 /mnt/sdcard/recovery
cp /mnt/sdcard/recovery/res/keys /mnt/sdcard/recovery/res/keys.org
echo " , {64,0xc926ad21,{1795090719,2141396315,950055447,-1713398866,-26044131,1920809988,546586521,-795969498,1776797858,-554906482,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,-1731647369,323993566,28517732,609753416,1826472888,215237850,-33324596,-245884705,-1066504894,774857746,154822455,-1797768399,-1536767878,-1275951968,-1500189652,87251430,-1760039318,120774784,571297800,-599067824,-1815042109,-483341846,-893134306,-1900097649,-1027721089,950095497,555058928,414729973,1136544882,-1250377212,465547824,-236820568,-1563171242,1689838846,-404210357,1048029507,895090649,247140249,178744550,-747082073,-1129788053,109881576,-350362881,1044303212,-522594267,-1309816990,-557446364,-695002876},{-857949815,-510492167,-1494742324,-1208744608,251333580,2131931323,512774938,325948880,-1637480859,2102694287,-474399070,792812816,1026422502,2053275343,-1494078096,-1181380486,165549746,-21447327,-229719404,1902789247,772932719,-353118870,-642223187,216871947,-1130566647,1942378755,-298201445,1055777370,964047799,629391717,-2062222979,-384408304,191868569,-1536083459,-612150544,-1297252564,-1592438046,-724266841,-518093464,-370899750,-739277751,-1536141862,1323144535,61311905,1997411085,376844204,213777604,-217643712,9135381,1625809335,-1490225159,-1342673351,1117190829,-57654514,1825108855,-1281819325,1111251351,-1726129724,1684324211,-1773988491,367251975,810756730,-1941182952,1175080310}}" >>/mnt/sdcard/recovery/res/keys
sync
umount /mnt/sdcard/recovery/
Just put it on your external sd card, name it user_script.sh. If everything was okay, you will find the script (after restarting the shine) renamed to user_script.sh.success. If anything went wrong and the script does not return 0 the file becomes user_script.sh.failure.
If you miss some links to busybox tools:
nice_to_have="touch chgrp cp diff find vi nc pidof grep tar zip unzip wget du sed watch more arp seq sleep usleep tail head wc"; for tool in $nice_to_have ; do ln /system/bin/busybox /system/bin/$tool ; done
downloads
file | content | size/mb | md5 |
---|---|---|---|
part_one.zip |
|
72 | 13362ef4bf5c73c9f9cfd0bd4f1628ce |
update_hugendubel_1_2_4_reworked_testkey.zip |
|
136 | b80ed49bdb04685975bae414ade5d538 |
shine_housing.zip | detailed pictures of the plastic enclosure of the shine (in case you have to open it – note the noses around the border of the back part, the top cover is also glued to the display frame and the housing of the connectors at the bottom with double sided tape – lift it carefully and slowly. maybe some warm air from a hairdryer removes some adhesive power. but be careful to not overheat the display – stay cool at all) | 0.7 | 31f8869f0de1c1ee3b3f629a1698dc69 |
Have phun!
First of all, thanks for your extensive work and providing us with valuable instructions on the Tolino Shine!
I have a question regarding the following restriction:
„If your shine is not rooted yet (and the serial number is below 20311241 – and you have not installed the update 1.2.4) you can just download.. []“
Why does the serial number have to be below 20311241? Are the new Tolino Shine 2 versions starting from that number?
Having a new Tolino Shine 2 with serial number 2034xxxx and firmware 1.2.0, am I somehow also able to get root?
Thanks and best regards!