MT6781 fixes, read speed improvements, dxcc improvements, minor bug fixes

This commit is contained in:
Bjoern Kerler 2024-07-22 14:58:13 +02:00
parent c5bc57d2b2
commit 1ffb152766
No known key found for this signature in database
GPG key ID: A3E0FAF79F2F4578
22 changed files with 397 additions and 173 deletions

122
README.md
View file

@ -171,12 +171,17 @@ sudo reboot
### Using MTKTools via the graphical user interface:
For the 'basics' you can use the GUI interface. This supports dumping partitions or the full flash for now. Run the following command:
```
python mtk_gui
python mtk_gui.py
```
### Using stock mtk functionality without exploits :
```
python mtk.py --stock
```
### Run multiple commands
```bash
python mtk script run.example
python mtk.py script run.example
```
See the file "[run.example](https://github.com/bkerler/mtkclient/blob/main/run.example)" on how to structure the script file
@ -184,12 +189,12 @@ See the file "[run.example](https://github.com/bkerler/mtkclient/blob/main/run.e
1. Dump boot and vbmeta
```
python mtk r boot,vbmeta boot.img,vbmeta.img
python mtk.py r boot,vbmeta boot.img,vbmeta.img
```
2. Reboot the phone
```
python mtk reset
python mtk.py reset
```
3. Download patched magisk for mtk:
@ -219,12 +224,12 @@ mv [displayed magisk patched boot filename here] boot.patched
8. Flash magisk-patched boot and empty vbmeta
```
python mtk w boot,vbmeta boot.patched,vbmeta.img.empty
python mtk.py w boot,vbmeta boot.patched,vbmeta.img.empty
```
9. Reboot the phone
```
python mtk reset
python mtk.py reset
```
10. Disconnect usb cable and enjoy your rooted phone :)
@ -235,7 +240,7 @@ python mtk reset
Example:
```
python mtk payload --metamode FASTBOOT
python mtk.py payload --metamode FASTBOOT
```
### Read efuses
@ -243,28 +248,28 @@ python mtk payload --metamode FASTBOOT
Example:
```
python mtk da efuse
python mtk.py da efuse
```
### Unlock bootloader
1. Erase metadata and userdata (and md_udc if existing):
```
python mtk e metadata,userdata,md_udc
python mtk.py e metadata,userdata,md_udc
```
2. Unlock bootloader:
```
python mtk da seccfg unlock
python mtk.py da seccfg unlock
```
for relocking use:
```
python mtk da seccfg lock
python mtk.py da seccfg lock
```
3. Reboot the phone:
```
python mtk reset
python mtk.py reset
```
and disconnect usb cable to let the phone reboot.
@ -279,57 +284,57 @@ then the device should boot within 5 seconds.
Dump boot partition to filename boot.bin via preloader
```
python mtk r boot boot.bin
python mtk.py r boot boot.bin
```
Dump boot partition to filename boot.bin via bootrom
```
python mtk r boot boot.bin [--preloader=Loader/Preloader/your_device_preloader.bin]
python mtk.py r boot boot.bin [--preloader=Loader/Preloader/your_device_preloader.bin]
```
Dump preloader partition to filename preloader.bin via bootrom
```
python mtk r preloader preloader.bin --parttype=boot1 [--preloader=Loader/Preloader/your_device_preloader.bin]
python mtk.py r preloader preloader.bin --parttype=boot1 [--preloader=Loader/Preloader/your_device_preloader.bin]
```
Read full flash to filename flash.bin (use --preloader for brom)
```
python mtk rf flash.bin
python mtk.py rf flash.bin
```
Read full flash to filename flash.bin (use --preloader for brom) for IoT devices (MT6261/MT2301):
```
python mtk rf flash.bin --iot
python mtk.py rf flash.bin --iot
```
Read flash offset 0x128000 with length 0x200000 to filename flash.bin (use --preloader for brom)
```
python mtk ro 0x128000 0x200000 flash.bin
python mtk.py ro 0x128000 0x200000 flash.bin
```
Dump all partitions to directory "out". (use --preloader for brom)
```
python mtk rl out
python mtk.py rl out
```
Show gpt (use --preloader for brom)
```
python mtk printgpt
python mtk.py printgpt
```
Mount the flash as a filesystem
```
python mtk fs /mnt/mtk
python mtk.py fs /mnt/mtk
```
### Write flash
@ -338,83 +343,83 @@ python mtk fs /mnt/mtk
Write filename boot.bin to boot partition
```
python mtk w boot boot.bin
python mtk.py w boot boot.bin
```
Write filename flash.bin as full flash (currently only works in da mode)
```
python mtk wf flash.bin
python mtk.py wf flash.bin
```
Write all files in directory "out" to the flash partitions
```
python mtk wl out
python mtk.py wl out
```
write file flash.bin to flash offset 0x128000 with length 0x200000 (use --preloader for brom)
```
python mtk wo 0x128000 0x200000 flash.bin
python mtk.py wo 0x128000 0x200000 flash.bin
```
### Erase flash
Erase boot partition
```
python mtk e boot
python mtk.py e boot
```
Erase boot sectors
```
python mtk es boot [sector count]
python mtk.py es boot [sector count]
```
### DA commands:
Peek memory
```
python mtk da peek [addr in hex] [length in hex] [optional: -filename filename.bin for reading to file]
python mtk.py da peek [addr in hex] [length in hex] [optional: -filename filename.bin for reading to file]
```
Poke memory
```
python mtk da poke [addr in hex] [data as hexstring or -filename for reading from file]
python mtk.py da poke [addr in hex] [data as hexstring or -filename for reading from file]
```
Read rpmb (Only xflash for now)
```
python mtk da rpmb r [will read to rpmb.bin]
python mtk.py da rpmb r [will read to rpmb.bin]
```
Write rpmb [Currently broken, xflash only]
```
python mtk da rpmb w filename
python mtk.py da rpmb w filename
```
Generate and display rpmb1-3 key
```
python mtk da generatekeys
python mtk.py da generatekeys
```
Unlock / Lock bootloader
```
python mtk da seccfg [lock or unlock]
python mtk.py da seccfg [lock or unlock]
```
---------------------------------------------------------------------------------------------------------------
### Bypass SLA, DAA and SBC (using generic_patcher_payload)
``
python mtk payload
python mtk.py payload
``
If you want to use SP Flash tool afterwards, make sure you select "UART" in the settings, not "USB".
### Dump preloader
- Device has to be in bootrom mode and preloader has to be intact on the device
```
python mtk dumppreloader [--ptype=["amonet","kamakiri","kamakiri2","hashimoto"]] [--filename=preloader.bin]
python mtk.py dumppreloader [--ptype=["amonet","kamakiri","kamakiri2","hashimoto"]] [--filename=preloader.bin]
```
### Dump brom
@ -425,12 +430,12 @@ python mtk dumppreloader [--ptype=["amonet","kamakiri","kamakiri2","hashimoto"]]
and "hashimoto" (via cqdma)
```
python mtk dumpbrom --ptype=["amonet","kamakiri","hashimoto"] [--filename=brom.bin]
python mtk.py dumpbrom --ptype=["amonet","kamakiri","hashimoto"] [--filename=brom.bin]
```
For to dump unknown bootroms, use brute option :
```
python mtk brute
python mtk.py brute
```
If it's successful, please add an issue over here and append the bootrom in order to add full support.
@ -439,39 +444,39 @@ If it's successful, please add an issue over here and append the bootrom in orde
### Crash da in order to enter brom
```
python mtk crash [--vid=vid] [--pid=pid] [--interface=interface]
python mtk.py crash [--vid=vid] [--pid=pid] [--interface=interface]
```
### Read memory using patched preloader
- Boot in Brom or crash to Brom
```
python mtk peek [addr] [length] --preloader=patched_preloader.bin
python mtk.py peek [addr] [length] --preloader=patched_preloader.bin
```
### Run custom payload
```
python mtk payload --payload=payload.bin [--var1=var1] [--wdt=wdt] [--uartaddr=addr] [--da_addr=addr] [--brom_addr=addr]
python mtk.py payload --payload=payload.bin [--var1=var1] [--wdt=wdt] [--uartaddr=addr] [--da_addr=addr] [--brom_addr=addr]
```
---------------------------------------------------------------------------------------------------------------
## Stage2 usage
### Run python mtk stage (brom) or mtk plstage (preloader)
### Run python mtk.py stage (brom) or mtk plstage (preloader)
#### Run stage2 in bootrom
``
python mtk stage
python mtk.py stage
``
#### Run stage2 in preloader
``
python mtk plstage
python mtk.py plstage
``
#### Run stage2 plstage in bootrom
- Boot in Brom or crash to Brom
```
python mtk plstage --preloader=preloader.bin
python mtk.py plstage --preloader=preloader.bin
```
### Use stage2 tool
@ -479,42 +484,42 @@ python mtk plstage --preloader=preloader.bin
### Leave stage2 and reboot
``
python stage2 reboot
python stage2.py reboot
``
### Read rpmb in stage2 mode
``
python stage2 rpmb
python stage2.py rpmb
``
### Read preloader in stage2 mode
``
python stage2 preloader
python stage2.py preloader
``
### Read memory as hex data in stage2 mode
``
python stage2 memread [start addr] [length]
python stage2.py memread [start addr] [length]
``
### Read memory to file in stage2 mode
``
python stage2 memread [start addr] [length] --filename filename.bin
python stage2.py memread [start addr] [length] --filename filename.bin
``
### Write hex data to memory in stage2 mode
``
python stage2 memwrite [start addr] --data [data as hexstring]
python stage2.py memwrite [start addr] --data [data as hexstring]
``
### Write memory from file in stage2 mode
``
python stage2 memwrite [start addr] --filename filename.bin
python stage2.py memwrite [start addr] --filename filename.bin
``
### Extract keys
``
python stage2 keys --mode [sej, dxcc]
python stage2.py keys --mode [sej, dxcc]
``
For dxcc, you need to use plstage instead of stage
@ -529,16 +534,3 @@ For dxcc, you need to use plstage instead of stage
### Chip details / configs
- Go to config/brom_config.py
- Unknown usb vid/pids for autodetection go to config/usb_ids.py
## Learning Resources
[MTK Preloader](https://o0xmuhe.github.io/2022/03/05/MTK-Preloader-踩坑/)
[MOSEC-2022](https://o0xmuhe.github.io/2022/11/23/议题解读-MOSEC2022-MediAttack-break-the-boot-chain-of-MediaTek-SoC/)
[Dissecting MTK BROM Exploit](https://tinyhack.com/2021/01/31/dissecting-a-mediatek-bootrom-exploit/)
[Dumping Exynos BROM](https://fredericb.info/2020/06/exynos8890-bootrom-dump-dump-exynos-8890-bootrom-from-samsung-galaxy-s7.html)
[Rev Exynos BROM USB STACK ](https://fredericb.info/2020/06/reverse-engineer-usb-stack-of-exynos-bootrom.html#reverse-engineer-usb-stack-of-exynos-bootrom)
[Buffer Overflow In Huawei BROM USB STACK](https://labs.taszk.io/blog/post/bootrom_usb/)

View file

@ -92,9 +92,15 @@ def main():
with open(loader, "rb") as rf:
rf.seek(mbuf)
data = rf.read(m_len)
test = data.find(b"\x01\x01\x54\xE3\x01\x14\xA0\xE3")
if test != -1:
print("V6 Device is patched against carbonara :(")
test=data.find(b"\x08\x00\xa8\x52\xff\x02\x08\xeb")
if test != -1:
print("Device is patched against carbonara :(")
print("V6 Device is patched against carbonara :(")
test2=data.find(b"\x06\x9B\x4F\xF0\x80\x40\x02\xA9")
if test2 != -1:
print("V5 Device is patched against carbonara :(")
hashidx = data.find(int.to_bytes(0xC0070004, 4, 'little'))
if hashidx != -1:
print("Hash check found.")
@ -111,7 +117,11 @@ def main():
if hashidx is not None:
print("Hash check 4 (V6) found.")
else:
print("HASH ERROR !!!!")
hashidx = find_binary(data,b"\x01\x10\x81\xE2\x00\x00\x51\xE1")
if hashidx is not None:
print("Hash check 5 (V6) found.")
else:
print("HASH ERROR !!!!")
fname = os.path.join("loaders",
hex(da[0]["hw_code"])[2:] + "_" + hex(startaddr)[2:] + os.path.basename(

13
learning_resources.md Normal file
View file

@ -0,0 +1,13 @@
## Learning Resources
[MTK Preloader](https://o0xmuhe.github.io/2022/03/05/MTK-Preloader-踩坑/)
[MOSEC-2022](https://o0xmuhe.github.io/2022/11/23/议题解读-MOSEC2022-MediAttack-break-the-boot-chain-of-MediaTek-SoC/)
[Dissecting MTK BROM Exploit](https://tinyhack.com/2021/01/31/dissecting-a-mediatek-bootrom-exploit/)
[Dumping Exynos BROM](https://fredericb.info/2020/06/exynos8890-bootrom-dump-dump-exynos-8890-bootrom-from-samsung-galaxy-s7.html)
[Rev Exynos BROM USB STACK ](https://fredericb.info/2020/06/reverse-engineer-usb-stack-of-exynos-bootrom.html#reverse-engineer-usb-stack-of-exynos-bootrom)
[Buffer Overflow In Huawei BROM USB STACK](https://labs.taszk.io/blog/post/bootrom_usb/)

20
mtk.py
View file

@ -942,6 +942,26 @@ if __name__ == '__main__':
da_dump.add_argument('--noreconnect', action="store_true", help='Disable reconnect')
da_rpmb.add_argument('--noreconnect', action="store_true", help='Disable reconnect')
parser_script.add_argument('--stock', action="store_true", help='use stock da')
parser_printgpt.add_argument('--stock', action="store_true", help='use stock da')
parser_footer.add_argument('--stock', action="store_true", help='use stock da')
parser_e.add_argument('--stock', action="store_true", help='use stock da')
parser_es.add_argument('--stock', action="store_true", help='use stock da')
parser_wl.add_argument('--stock', action="store_true", help='use stock da')
parser_wf.add_argument('--stock', action="store_true", help='use stock da')
parser_w.add_argument('--stock', action="store_true", help='use stock da')
parser_rs.add_argument('--stock', action="store_true", help='use stock da')
parser_rf.add_argument('--stock', action="store_true", help='use stock da')
parser_rl.add_argument('--stock', action="store_true", help='use stock da')
parser_gpt.add_argument('--stock', action="store_true", help='use stock da')
parser_r.add_argument('--stock', action="store_true", help='use stock da')
da_keys.add_argument('--stock', action="store_true", help='use stock da')
da_unlock.add_argument('--stock', action="store_true", help='use stock da')
da_peek.add_argument('--stock', action="store_true", help='use stock da')
da_poke.add_argument('--stock', action="store_true", help='use stock da')
da_dump.add_argument('--stock', action="store_true", help='use stock da')
da_rpmb.add_argument('--stock', action="store_true", help='use stock da')
parser_script.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)')
parser_printgpt.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)')
parser_footer.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)')

View file

@ -33,6 +33,12 @@ class SlaKey:
da_sla_keys = [
SlaKey(vendor="Tecno/Infinix",
da_codes=[0x1208, 0x0907],
name="",
d="499890AEF768030B56AD8BF7355262A57643A8C3DF318647B72E0B72416D91D25882D0077FEBE9E8275E9F42C3F89FFF5E99E0163487461B7CC3E97C1CC4F4E2D587AB7D8DB80335AA8E3254F318AAC42136FF1043649918685A0F5CF5548318090C26D951A2B93F79FB0D9B5E1DB1C928091E1908A5DA7D3B9194A22B18B78C6EF88932EFB3D88DB8BA7117257063DE165FA8534D50C6B35F6F7C0AF5F4A96BB89756BB7AC94110E8D1B5868A5DAADF815FE8FA38960A039D681F319C7B7ED7A55649C2F2F75B26C27807AFED8BC4EF57619FF9DA152E337FE379E1B1B0020C1EF2ABDCE4A66AAF3802EE8AB105ACA6F3388EA4C20184E572778C8EB3D30B51",
n="BA4C5178EE5477B7A30FC99F9FE78E7C011E58B5DC05832591AADEE0D26A2667738FFE851782016CAE7DB8DC1958C627BC60E3A96D46E225536DCC76CBFADFE6CA2CBE4BE982AB46CBB0F1C5CB2CB13D7BBAC96E467D76AF819DCA28FB90A03AF92DDC05B34506E24F02A049D73B8143A1CF4B081372D49F4BCA21DA9EE8A19679669C71C836FC5B8180BD98256BA2AE82B702DDC61EDFD9C47871D027297D6C72A984046081953D141656F0DC4BC4E2D4006147BE096D7E855AA7057460EAC7C57660F1F28BE278C38700BAC5EBADB39F6508CF2F1E4044421664A856623FFB2002C1204CED786D576E3DDAA7C185FD698B1185A98A03B875F0A93831270557",
e="010001"),
# lk/files/pbp/keys/toolauth/da_prvk.pem
SlaKey(vendor="KaiOS",
da_codes=[],
@ -47,14 +53,6 @@ da_sla_keys = [
d="09976537029b4362591c5b13873f223de5525d55df52dde283e52afa67f6c9dbf1408d2fb586a624efc93426f5f3be981f80e861ddd975a1e5e662db84f5164804a3ae717605d7f15866df9ed1497c38fdd6197243163ef22f958d7b822c57317203e9a1e7d18dad01f15054facdbddb9261a1272638da661fe4f9f0714ecf00e6541cc435afb1fd75a27d34b17ad400e9474ba850dafce266799caff32a058ff71e4c2daacaf8ba709e9ca4dc87584a7ffe8aa9a0a160ed069c3970b7dae3987ded71bd0bc824356987bd74363d46682c71913c3edbdb2a911f701f23aee3f8dd98180b5a138fd5ad74743682d2d2d1bb3d92786710248f316dd8391178ea81",
n="D16403466C530EF9BB53C1E8A96A61A4E332E17DC0F55BB46D207AC305BAE9354EAAC2CB3077B33740D275036B822DB268200DE17DA3DB7266B27686B8970B85737050F084F8D576904E74CD6C53B31F0BB0CD60686BF67C60DA0EC20F563EEA715CEBDBF76D1C5C10E982AB2955D833DE553C9CDAFD7EA2388C02823CFE7DD9AC83FA2A8EB0685ABDAB56A92DF1A7805E8AC0BD10C0F3DCB1770A9E6BBC3418C5F84A48B7CB2316B2C8F64972F391B116A58C9395A9CE9E743569A367086D7771D39FEC8EBBBA3DD2B519785A76A9F589D36D637AF884543FD65BAC75BE823C0C50AA16D58187B97223625C54C66B5A5E4DBAEAB7BE89A4E340A2E241B09B2F",
e="010001"),
"""
SlaKey(vendor="Generic",
da_codes=[],
name="VERIFIED_BOOT_IMG_AUTH_KEY.ini",
d=0xDACD8B5FDA8A766FB7BCAA43F0B16915CE7B47714F1395FDEBCF12A2D41155B0FB587A51FECCCB4DDA1C8E5EB9EB69B86DAF2C620F6C2735215A5F22C0B6CE377AA0D07EB38ED340B5629FC2890494B078A63D6D07FDEACDBE3E7F27FDE4B143F49DB4971437E6D00D9E18B56F02DABEB0000B6E79516D0C8074B5A42569FD0D9196655D2A4030D42DFE05E9F64883E6D5F79A5BFA3E7014C9A62853DC1F21D5D626F4D0846DB16452187DD776E8886B48C210C9E208059E7CAFC997FD2CA210775C1A5D9AA261252FB975268D970C62733871D57814098A453DF92BC6CA19025CD9D430F02EE46F80DE6C63EA802BEF90673AAC4C6667F2883FB4501FA77455,
n=0x8BC9B1F7A559BCDD1717F3F7BFF8B858743892A6338D21D0BE2CE78D1BCB8F61A8D31822F694C476929897E4B10753DDBE45A2276C0EFEE594CF75E47016DA9CDB3D8EB6C3E4C5D69B8BCCE1AE443CF299C22B905300C85875E8DBB8231F4E9949D8CF9D8E0F40E93F29F843420F22CD9D080A45A4407F58F3609D03A7DB950D3D847B8B4E7D50DB6359D37A2DD730D3CE77F8FB2A33C095B0A6CF3E08593E4F70254DCDF671790F530EC07C3CD1E80199CB42F24ACA92DB5996F2119003F502E16D88EB4E4A8DEAE4036558D2A52F5C9960B0FBBC6F6FA75EFF6F5A173CE1A82539A35973D568B8918ED12F7610748BEB0239A5006257E19574C77F4133A269,
e="010001"),
""",
SlaKey(vendor="Generic",
da_codes=[],
name="CodeSigKey",
@ -69,6 +67,23 @@ da_sla_keys = [
e="010001"),
]
"""
SlaKey(vendor="Generic",
da_codes=[],
name="VERIFIED_BOOT_IMG_AUTH_KEY.ini",
d=0xDACD8B5FDA8A766FB7BCAA43F0B16915CE7B47714F1395FDEBCF12A2D41155B0FB587A51FECCCB4DDA1C8E5EB9EB69B86DAF2C620F6C2735215A5F22C0B6CE377AA0D07EB38ED340B5629FC2890494B078A63D6D07FDEACDBE3E7F27FDE4B143F49DB4971437E6D00D9E18B56F02DABEB0000B6E79516D0C8074B5A42569FD0D9196655D2A4030D42DFE05E9F64883E6D5F79A5BFA3E7014C9A62853DC1F21D5D626F4D0846DB16452187DD776E8886B48C210C9E208059E7CAFC997FD2CA210775C1A5D9AA261252FB975268D970C62733871D57814098A453DF92BC6CA19025CD9D430F02EE46F80DE6C63EA802BEF90673AAC4C6667F2883FB4501FA77455,
n=0x8BC9B1F7A559BCDD1717F3F7BFF8B858743892A6338D21D0BE2CE78D1BCB8F61A8D31822F694C476929897E4B10753DDBE45A2276C0EFEE594CF75E47016DA9CDB3D8EB6C3E4C5D69B8BCCE1AE443CF299C22B905300C85875E8DBB8231F4E9949D8CF9D8E0F40E93F29F843420F22CD9D080A45A4407F58F3609D03A7DB950D3D847B8B4E7D50DB6359D37A2DD730D3CE77F8FB2A33C095B0A6CF3E08593E4F70254DCDF671790F530EC07C3CD1E80199CB42F24ACA92DB5996F2119003F502E16D88EB4E4A8DEAE4036558D2A52F5C9960B0FBBC6F6FA75EFF6F5A173CE1A82539A35973D568B8918ED12F7610748BEB0239A5006257E19574C77F4133A269,
e="010001"),
""",
"""SlaKey(vendor="Generic",
da_codes=[],
name="AuthGen_SV5.ini",
d="9a3c3d4da0650cef38ed96ef833904c9c13835199367c7b9cb03a55e7aa482016a820dfe597cd54dd1f81fd879cf070ec0c25899ac5a49822db09675a92acf6a01e0f8f538bbe66de48ca9bdca313b616470d9ec2914356d03c95f7d9236549e5a21457e4dd5fcaf09046c47ca7436f06cd7b82cb6d2a936fca88b707f6ce28f33110fea1ec363e8482419db901cb0d38e574fe0c02ad117166b40ec78f59aaa7f3eafa425010a95614e046651273a6cb1371380c4e6ce81bdb892db6ff4892cc4d8c613a8fb3fec1e72c279052896872fc23da07fba63783374f3be8e16a15e0a04a139108dd6ac239f191135f4a895e27c670de065d2248e3f9c7e920fd001",
n="008C8BF38EB2FC7FC06D567DBF70E9C34BE4281C4239ED9C58A6B598C3AE7821815D94D0B463463EEBBD69FF6AF990AE0499B6C3B3CADCD91D54499CD66E5314DB610FC0C6CAEEB1F16B6F2D451E3F2B2D515008917FCEC50ADA4CE0699BCF247D5AE2A1DDD34C48624A657CCB11CE5F8C6CE92CAB6038EFC2A89E42E029488C02C3CF21947C86D51BBA8EF540A2A7CE85356F431891261D860B518E89DD73B2D240461ACB66BCC213403145DE83F6963147E65274EA1E45DB2D231E0774ECC86E4F2328F8A90835C4FDEF1088DDBA1D8F7CA0CA732A64BDA6816162C0F88F02CF97634D85530968CBF8B7CE6A8B67D53BBFB4910843EA413135D56FB5074445",
e="010001"),
"""
brom_sla_keys = [
SlaKey(vendor="Generic",
da_codes=[],
@ -76,13 +91,6 @@ brom_sla_keys = [
d="4BD992E9A2230CD2ABEF49E4F6A7E11D7E2ADD24847787B320239829C560D5EAB94B8304317C938E9358E94758AE60D9B13F2913DD1A749A9941FACAFAB574D70EBBFBCC0133A4BE2134CBA3CE7EE18A6D3CC98D33DAB06AEEE512F405A3248EA316ABC31A2758D4C5A7B9DFCC02C2508A492EF3760A0D4CDA827CFFCADD11ED",
n="5FFF0B70D5DE3FC5BF41CB824B4BFD14820571CE57EDD3E7C668CC570E718DB07DCC7A6CACD0E80DADC38AA33DB37816839D97980DF3E577A6E0B1169D708071E17DD259CFE538DBDA804A2FC07D795841F2F59DEE023A9919360D0A3F4647FDF5657D9FC5944C8BFA2802336BA23AFDCDE8D546E8806EB532AA7F95A01D8DD1",
e="010001"),
"""SlaKey(vendor="Generic",
da_codes=[],
name="AuthGen_SV5.ini",
d="9a3c3d4da0650cef38ed96ef833904c9c13835199367c7b9cb03a55e7aa482016a820dfe597cd54dd1f81fd879cf070ec0c25899ac5a49822db09675a92acf6a01e0f8f538bbe66de48ca9bdca313b616470d9ec2914356d03c95f7d9236549e5a21457e4dd5fcaf09046c47ca7436f06cd7b82cb6d2a936fca88b707f6ce28f33110fea1ec363e8482419db901cb0d38e574fe0c02ad117166b40ec78f59aaa7f3eafa425010a95614e046651273a6cb1371380c4e6ce81bdb892db6ff4892cc4d8c613a8fb3fec1e72c279052896872fc23da07fba63783374f3be8e16a15e0a04a139108dd6ac239f191135f4a895e27c670de065d2248e3f9c7e920fd001",
n="008C8BF38EB2FC7FC06D567DBF70E9C34BE4281C4239ED9C58A6B598C3AE7821815D94D0B463463EEBBD69FF6AF990AE0499B6C3B3CADCD91D54499CD66E5314DB610FC0C6CAEEB1F16B6F2D451E3F2B2D515008917FCEC50ADA4CE0699BCF247D5AE2A1DDD34C48624A657CCB11CE5F8C6CE92CAB6038EFC2A89E42E029488C02C3CF21947C86D51BBA8EF540A2A7CE85356F431891261D860B518E89DD73B2D240461ACB66BCC213403145DE83F6963147E65274EA1E45DB2D231E0774ECC86E4F2328F8A90835C4FDEF1088DDBA1D8F7CA0CA732A64BDA6816162C0F88F02CF97634D85530968CBF8B7CE6A8B67D53BBFB4910843EA413135D56FB5074445",
e="010001"),
""",
SlaKey(vendor="Generic",
da_codes=[],
name="ROWAN / 0_2048_key.pem / CHIP_TEST_KEY.ini / lk/files/pbp/keys/toolauth/sla_prvk.pem",

View file

@ -81,7 +81,7 @@ class DeviceClass(metaclass=LogBase):
def usbwrite(self, data, pktsize=None):
raise NotImplementedError()
def usbread(self, resplen=None, timeout=0):
def usbread(self, resplen=None, timeout=0, w_max_packet_size=None):
raise NotImplementedError()
def usbxmlread(self, maxtimeout=100):

View file

@ -4,11 +4,14 @@
import time
import sys
import logging
from queue import Queue
from mtkclient.Library.DA.xml.xml_param import max_xml_data_length
import serial
import serial.tools.list_ports
import inspect
from mtkclient.Library.Connection.devicehandler import DeviceClass
if sys.platform != "win32":
import termios
@ -28,6 +31,7 @@ class SerialClass(DeviceClass):
super().__init__(loglevel, portconfig, devclass)
self.is_serial = True
self.device = None
self.queue = Queue()
def connect(self, ep_in=-1, ep_out=-1):
if self.connected:
@ -193,7 +197,7 @@ class SerialClass(DeviceClass):
self.device.flushOutput()
return self.device.flush()
def usbread(self, resplen=None, maxtimeout=0, timeout=0):
def usbread(self, resplen=None, maxtimeout=0, timeout=0, w_max_packet_size=None):
# print("Reading {} bytes".format(resplen))
if timeout == 0 and maxtimeout != 0:
timeout = maxtimeout / 1000 # Some code calls this with ms delays, some with seconds.
@ -209,14 +213,26 @@ class SerialClass(DeviceClass):
return b""
self.device.timeout = timeout
epr = self.device.read
q = self.queue
extend = res.extend
bytestoread = resplen
while len(res) < bytestoread:
while bytestoread:
bytestoread = resplen - len(res) if len(res) < resplen else 0
if not q.empty():
data = q.get(bytestoread)
extend(data)
if bytestoread <= 0:
break
try:
val = epr(bytestoread)
if len(val) == 0:
break
extend(val)
if len(val) > bytestoread:
self.warning("Buffer overflow")
q.put(val[bytestoread:])
extend(val[:bytestoread])
else:
extend(val)
except Exception as e:
error = str(e)
if "timed out" in error:

View file

@ -4,6 +4,7 @@
import logging
import os
import sys
from queue import Queue
import usb.core # pyusb
import usb.util
import time
@ -127,6 +128,7 @@ class UsbClass(DeviceClass):
self.EP_IN = None
self.EP_OUT = None
self.is_serial = False
self.queue = Queue()
if sys.platform.startswith('freebsd') or sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
self.backend = usb.backend.libusb1.get_backend(find_library=lambda x: "libusb-1.0.so")
elif sys.platform.startswith('win32'):
@ -376,8 +378,8 @@ class UsbClass(DeviceClass):
self.EP_IN = usb.util.find_descriptor(itf,
# match the first OUT endpoint
custom_match=lambda xe: \
usb.util.endpoint_direction(xe.bEndpointAddress) ==
usb.util.ENDPOINT_IN)
usb.util.endpoint_direction(xe.bEndpointAddress) ==
usb.util.ENDPOINT_IN)
self.connected = True
return True
print("Couldn't find CDC interface. Aborting.")
@ -456,7 +458,7 @@ class UsbClass(DeviceClass):
def get_write_packetsize(self):
return self.EP_OUT.wMaxPacketSize
def usbread(self, resplen=None, maxtimeout=100):
def usbread(self, resplen=None, maxtimeout=100, w_max_packet_size=None):
if resplen is None:
resplen = self.maxsize
if resplen <= 0:
@ -465,19 +467,38 @@ class UsbClass(DeviceClass):
timeout = 0
loglevel = self.loglevel
epr = self.EP_IN.read
w_max_packet_size = self.EP_IN.wMaxPacketSize
q = self.queue
b = self.buffer
if w_max_packet_size is None:
w_max_packet_size = self.EP_IN.wMaxPacketSize
extend = res.extend
fast = self.fast
buffer = None
buflen = min(resplen, w_max_packet_size)
if self.fast:
buffer = self.buffer[:buflen]
while len(res) < resplen:
buffer = b[:buflen]
bytestoread = resplen
while bytestoread > 0:
bytestoread = resplen - len(res) if len(res) < resplen else 0
if not q.empty():
extend(q.get(bytestoread))
if bytestoread <= 0:
break
sz = min(buflen, bytestoread)
try:
if self.fast:
if fast:
rlen = epr(buffer, timeout)
if rlen > sz:
self.warning("Buffer overflow")
q.put(buffer[rlen:])
if self.loglevel == logging.DEBUG:
self.warning(traceback.format_exc())
self.warning(f"{rlen} vs {sz}")
self.warning(buffer[sz:].hex())
sys.stdout.flush()
extend(buffer[:rlen])
else:
extend(epr(buflen))
extend(epr(sz))
except usb.core.USBError as e:
error = str(e.strerror)
if "timed out" in error:
@ -489,6 +510,9 @@ class UsbClass(DeviceClass):
elif "Overflow" in error:
self.error("USB Overflow")
return b""
elif "No such device" in error:
self.error("Device disconnected")
sys.exit(1)
else:
self.info(repr(e))
return b""

View file

@ -256,6 +256,8 @@ class DAconfig(metaclass=LogBase):
if loader.hw_version <= self.config.hwver:
if loader.sw_version <= self.config.swver:
if self.da_loader is None:
if loader.v6:
self.config.chipconfig.damode = DAmodes.XML
self.da_loader = loader
self.loader = loader.loader
if self.da_loader is None and dacode != 0x6261:

View file

@ -809,6 +809,8 @@ class DALegacy(metaclass=LogBase):
res = self.usbread(1)
if res == self.Rsp.ACK:
speed = self.usbread(1)
if speed[0] > 0:
self.mtk.port.cdc.set_fast_mode(True)
return speed
return None
@ -1099,7 +1101,7 @@ class DALegacy(metaclass=LogBase):
size = bytestoread
if bytestoread > packetsize:
size = packetsize
tmp = self.usbread(size)
tmp = self.usbread(size, w_max_packet_size=size)
rq.put(tmp[:size])
bytestoread -= size
curpos += size
@ -1124,8 +1126,8 @@ class DALegacy(metaclass=LogBase):
size = bytestoread
if bytestoread > packetsize:
size = packetsize
buffer.extend(self.usbread(size))
bytestoread -= size
buffer.extend(self.usbread(size, w_max_packet_size=size))
bytestoread = len(buffer)-length
checksum = unpack(">H", self.usbread(2))[0]
self.debug("Checksum: %04X" % checksum)
self.usbwrite(self.Rsp.ACK)

View file

@ -832,22 +832,28 @@ class DAXFlash(metaclass=LogBase):
worker.start()
while bytestoread > 0:
status = self.usbread(4 + 4 + 4)
magic, datatype, slength = unpack("<III", status)
if magic == 0xFEEEEEEF:
resdata = self.usbread(slength)
if slength > 4:
rq.put(resdata)
stmp = pack("<III", self.Cmd.MAGIC, self.DataType.DT_PROTOCOL_FLOW, 4)
data = pack("<I", 0)
self.usbwrite(stmp)
self.usbwrite(data)
bytestoread -= len(resdata)
bytesread += len(resdata)
if display:
self.mtk.daloader.progress.show_progress("Read", bytesread, total, display)
elif slength == 4:
if unpack("<I", resdata)[0] != 0:
break
try:
magic, datatype, slength = unpack("<III", status)
if magic == 0xFEEEEEEF:
resdata = self.usbread(slength, w_max_packet_size=slength)
if slength > 4:
rq.put(resdata)
stmp = pack("<III", self.Cmd.MAGIC, self.DataType.DT_PROTOCOL_FLOW, 4)
data = pack("<I", 0)
self.usbwrite(stmp)
self.usbwrite(data)
bytestoread -= len(resdata)
bytesread += len(resdata)
if display:
self.mtk.daloader.progress.show_progress("Read", bytesread, total, display)
elif slength == 4:
if unpack("<I", resdata)[0] != 0:
break
else:
print("Error: Invalid slength")
except:
print("Error: Timeout")
status = self.usbread(4 + 4 + 4)
magic, datatype, slength = unpack("<III", status)
if magic == 0xFEEEEEEF:
@ -1054,7 +1060,7 @@ class DAXFlash(metaclass=LogBase):
da2sig_len = self.daconfig.da_loader.region[2].m_sig_len
bootldr.seek(da2offset)
da2 = bootldr.read(self.daconfig.da_loader.region[2].m_len)
if self.patch or not self.config.target_config["sbc"]:
if self.patch or not self.config.target_config["sbc"] and not self.config.stock:
da1, da2 = self.patch_da(da1, da2)
else:
self.patch = False
@ -1141,11 +1147,13 @@ class DAXFlash(metaclass=LogBase):
for key in da_sla_keys:
if da2.find(bytes.fromhex(key.n)) != -1:
sla_signature = generate_da_sla_signature(data=data, key=key.key)
found = not self.set_remote_sec_policy(data=sla_signature)
found = self.set_remote_sec_policy(data=sla_signature)
if found:
break
if not found:
print("No valid sla key found, using dummy auth ....")
sla_signature = b"\x00" * 0x100
found = not self.set_remote_sec_policy(data=sla_signature)
found = self.set_remote_sec_policy(data=sla_signature)
if found:
print("SLA Signature was accepted.")
return found
@ -1210,12 +1218,10 @@ class DAXFlash(metaclass=LogBase):
if stage == 1:
self.info("Uploading stage 2...")
stage = stage + 1
if not self.mtk.daloader.patch:
#if self.carbonara is not None:
# loaded = self.carbonara.patchda1_and_upload_da2()
#else:
loaded = False
if not self.mtk.daloader.patch and not self.mtk.config.stock and connagent == b"preloader":
loaded = self.boot_to(self.daconfig.da_loader.region[stage].m_start_addr, self.daconfig.da2)
else:
if not loaded:
loaded = self.boot_to(self.daconfig.da_loader.region[stage].m_start_addr, self.daconfig.da2)
if loaded:
self.info("Successfully uploaded stage 2")
@ -1224,7 +1230,6 @@ class DAXFlash(metaclass=LogBase):
self.info("DA SLA is enabled")
if not self.handle_sla(self.daconfig.da2):
self.error("Can't bypass DA SLA")
sys.exit(1)
else:
self.info("DA SLA is disabled")
self.reinit(True)

View file

@ -635,12 +635,14 @@ class XmlFlashExt(metaclass=LogBase):
if rpartition.name == "seccfg":
partition = rpartition
seccfg_data = self.xflash.readflash(
addr=partition.sector * self.mtk.daloader.daconfig.pagesize,
length=partition.sectors * self.mtk.daloader.daconfig.pagesize,
addr=partition.sector * guid_gpt.sectorsize,
length=partition.sectors * guid_gpt.sectorsize,
filename="", parttype="user", display=False)
break
if seccfg_data is None:
return False, "Couldn't detect existing seccfg partition. Aborting unlock."
if seccfg_data.find(b"\x4D\x4D\x4D\x4D") == -1:
return False, "SecCfg is empty. Aborting unlock."
if seccfg_data[:4] != pack("<I", 0x4D4D4D4D):
return False, "Unknown seccfg partition header. Aborting unlock."
hwc = self.cryptosetup()
@ -766,6 +768,8 @@ class XmlFlashExt(metaclass=LogBase):
self.info(f"CID : {cid}")
retval["cid"] = cid
if self.config.chipconfig.dxcc_base is not None:
# self.info("Generating provision key...")
# platkey, provkey = hwc.aes_hwcrypt(btype="dxcc", mode="prov")
self.info("Generating dxcc rpmbkey...")
rpmbkey = hwc.aes_hwcrypt(btype="dxcc", mode="rpmb")
self.info("Generating dxcc mirpmbkey...")

View file

@ -6,7 +6,11 @@ import os
from struct import pack, unpack
from queue import Queue
from threading import Thread
from Cryptodome.Util.number import size
from Cryptodome.Cipher import PKCS1_OAEP
from Cryptodome.Hash import SHA256
from Cryptodome.PublicKey import RSA
from Cryptodome.Util.number import size, bytes_to_long
from mtkclient.Library.DA.xml.xml_param import DataType, FtSystemOSE, LogLevel
from mtkclient.Library.utils import logsetup, LogBase
from mtkclient.Library.error import ErrorHandler
@ -228,7 +232,7 @@ class DAXML(metaclass=LogBase):
bytestoread = length
while bytestoread > 0:
sz = min(usbepsz, bytestoread)
data.extend(self.usbread(sz))
data.extend(self.usbread(sz,w_max_packet_size=sz))
bytestoread -= sz
if len(data) == length:
return data

View file

@ -61,7 +61,7 @@ class HwCrypto(metaclass=LogBase):
return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=True)
elif mode == "sst":
self.sej.sej_base = 0xC0016000
data2 = self.sej.generate_hw_meta(encrypt=True, data=data)
data2 = self.sej.generate_hw_meta(encrypt=True, data=data, legacy=False)
data3 = self.sej.sst_secure_algo_with_level(buf=data, encrypt=True)
print(data2.hex())
print(data3.hex())

View file

@ -12,6 +12,14 @@ from Cryptodome.Cipher import AES
from Cryptodome.Util import Counter
from mtkclient.Library.utils import LogBase, logsetup
Lcs = 0xA
KceSet = 0xB
Kce = 0xC # CodeEncryptionKey
SASI_SB_HASH_BOOT_KEY_256B = 2 # 0x10
SASI_SB_HASH_BOOT_KEY_1_128B = 1 # 0x14
SASI_SW_VERSION_COUNTER1 = 1 # 0x18
SASI_SW_VERSION_COUNTER2 = 2 # 0x19
oem_pubk = "DACD8B5FDA8A766FB7BCAA43F0B16915" + \
"CE7B47714F1395FDEBCF12A2D41155B0" + \
"FB587A51FECCCB4DDA1C8E5EB9EB69B8" + \
@ -1114,6 +1122,18 @@ class Dxcc(metaclass=LogBase):
self.tzcc_clk(0)
return rpmbkey
def sasi_bsv_socid_compute(self):
key = bytes.fromhex("49")
salt = b"\x00"*32
keylength = 0x10
self.tzcc_clk(1)
dstaddr = self.da_payload_addr - 0x300
pubkey = self.sasi_bsv_pubkey_hash_get(SASI_SB_HASH_BOOT_KEY_256B)
derivedkey = self.sbrom_key_derivation(1, key, salt, keylength, dstaddr)
hash = hashlib.sha256(pubkey+derivedkey).digest()
self.tzcc_clk(0)
return hash
def generate_rpmb_mitee(self):
rpmb_ikey = bytes.fromhex("AD1AC6B4BDF4EDB7")
rpmb_salt = bytes.fromhex("69EF6584")
@ -1124,37 +1144,120 @@ class Dxcc(metaclass=LogBase):
self.tzcc_clk(0)
return rpmbkey
def salt_func(self, value):
def sasi_bsv_otp_word_read(self, otpAddress):
if otpAddress>0x24:
return None
while True:
val = self.read32(self.dxcc_base + (0x2AF * 4)) & 1
if val != 0:
break
self.write32(self.dxcc_base + (0x2A9 * 4), (4 * value) | 0x10000)
self.write32(self.dxcc_base + (0x2A9 * 4), (4 * otpAddress) | 0x10000)
while True:
val = self.read32(self.dxcc_base + (0x2AD * 4)) << 31
val = self.read32(self.dxcc_base + (0x2AD * 4)) & 1
if val != 0:
break
res = self.read32(self.dxcc_base + (0x2AB * 4))
return res
def sasi_bsv_lcs_get(self):
while True:
val = self.read32(self.dxcc_base + (0x2AF * 4)) & 1
if val != 0:
break
lcs = self.read32(self.dxcc_base + (0x2B5 * 4))
if lcs != 1:
if lcs != 5:
return 0
if self.read32(self.dxcc_base + (0x2B5 * 4)) & 0x100 != 0:
return 0xB000002
otp_word = self.sasi_bsv_otp_word_read(0xA)
if self.read32(self.dxcc_base + (0x2B5 * 4)) & 0x100 != 0:
if otp_word & 0xF0000 != 0x30000:
return 0xB000080
if self.read32(self.dxcc_base + (0x2B5 * 4)) & 0x200 == 0:
return 0
return 0xB000003
def sasi_bsv_pub_key_hash_get(self, keyindex=SASI_SB_HASH_BOOT_KEY_256B):
if keyindex == SASI_SB_HASH_BOOT_KEY_256B:
start = 0x10
length = 0x8
elif keyindex == SASI_SB_HASH_BOOT_KEY_1_128B:
start = 0x14
length = 0x4
else:
return None
hashval = bytearray()
for idx in range(start,start+length,0x1):
hashval.extend(int.to_bytes(self.sasi_bsv_otp_word_read(idx),4,'little'))
return hashval
def sbrom_decrypt_kcst(self):
pdesc = hw_desc_init()
pdesc[0] = 0
pdesc[1] = 0x3FFC000
pdesc[2] = 0
pdesc[3] = 0
pdesc[4] = 0
pdesc[5] = 0
self.sasi_sb_adddescsequence(pdesc)
self.sb_hal_wait_desc_completion()
def sbrom_aeslockenginekey(self):
pdesc = hw_desc_init()
pdesc[0] = 0
pdesc[1] = 0x8000081
pdesc[2] = 0
pdesc[3] = 0
pdesc[4] = 0x4801C20
pdesc[5] = 0
self.sasi_sb_adddescsequence(pdesc)
self.sb_hal_wait_desc_completion()
def sasi_bsv_customer_key_decrypt(self):
plat_key = b"KEY PLAT"
dstaddr = self.da_payload_addr - 0x300
salt = self.sasi_bsv_pub_key_hash_get(keyindex=SASI_SB_HASH_BOOT_KEY_256B)
platkey = self.sbrom_key_derivation(HwCryptoKey.PLATFORM_KEY, plat_key, salt, 0x10, dstaddr)
while True:
val = self.read32(self.dxcc_base + 0xAF4) & 1
if val != 0:
break
self.sbrom_decrypt_kcst()
while True:
val = self.read32(self.dxcc_base + 0xAF0) & 1
if val != 0:
break
self.write32(self.dxcc_base + 0xAC0, 0)
self.write32(self.dxcc_base + 0xAC4, 0)
self.write32(self.dxcc_base + 0xAC8, 0)
self.write32(self.dxcc_base + 0xACC, 0)
self.sbrom_aeslockenginekey()
def sasi_bsv_security_disable(self):
lcs = self.sasi_bsv_lcs_get()
if lcs == 7:
return
self.write32(self.dxcc_base + 0xAC0, 0)
self.write32(self.dxcc_base + 0xAC4, 0)
self.write32(self.dxcc_base + 0xAC8, 0)
self.write32(self.dxcc_base + 0xACC, 0)
self.write32(self.dxcc_base + 0xAD8, 1)
def generate_provision_key(self):
plat_key = b"KEY PLAT"
prov_key = b"PROVISION KEY"
self.tzcc_clk(1)
dstaddr = self.da_payload_addr - 0x300
salt = hashlib.sha256(bytes.fromhex(oem_pubk)).digest()
"""
salt = bytearray(b"\x00"*0x20)
for i in range(8):
salt[i*4]=self.salt_func(0x10+i)
"""
provkey = self.sbrom_key_derivation(HwCryptoKey.PROVISIONING_KEY, plat_key, salt, 0x10, dstaddr)
lcs = self.sasi_bsv_lcs_get()
#salt = hashlib.sha256(bytes.fromhex(oem_pubk)).digest()
salt = self.sasi_bsv_pub_key_hash_get(keyindex=SASI_SB_HASH_BOOT_KEY_256B)
platkey = self.sbrom_key_derivation(HwCryptoKey.PLATFORM_KEY, plat_key, salt, 0x10, dstaddr)
while True:
val = self.read32(self.dxcc_base + 0xAF4) & 1
if val != 0:
break
platkey = self.sbrom_key_derivation(HwCryptoKey.PLATFORM_KEY, prov_key, salt, 0x10, dstaddr)
provkey = self.sbrom_key_derivation(HwCryptoKey.PROVISIONING_KEY, prov_key, salt, 0x10, dstaddr)
self.write32(self.dxcc_base + 0xAC0, 0)
self.write32(self.dxcc_base + 0xAC4, 0)
self.write32(self.dxcc_base + 0xAC8, 0)
@ -1183,7 +1286,7 @@ class Dxcc(metaclass=LogBase):
def sbrom_key_derivation(self, aeskeytype, label, salt, requestedlen, destaddr):
result = bytearray()
if aeskeytype - 1 > 4 or (1 << (aeskeytype - 1) & 0x17) == 0:
if aeskeytype <= HwCryptoKey.PLATFORM_KEY or (1 << (aeskeytype - 1) & 0x17) == 0:
return 0xF2000002
if requestedlen > 0xFF or (requestedlen << 28) & 0xFFFFFFFF:
return 0xF2000003

View file

@ -468,7 +468,7 @@ class Sej(metaclass=LogBase):
self.reg.HACC_ACON|=acon_setting
"""
def sst_secure_algo_with_level(self, buf, encrypt=True, aes_top_legacy=True):
def sst_secure_algo_with_level(self, buf, encrypt=True, aes_top_legacy=True, legacyxor=True):
seed = (CustomSeed[2] << 16) | (CustomSeed[1] << 8) | CustomSeed[0] | (CustomSeed[3] << 24)
_iv = [seed, (~seed) & 0xFFFFFFFF, (((seed >> 16) | (seed << 16)) & 0xFFFFFFFF),
(~((seed >> 16) | (seed << 16)) & 0xFFFFFFFF)]
@ -502,11 +502,11 @@ class Sej(metaclass=LogBase):
self.sej_aes_hw_init(attr, key, sej_param)
for pos in range(3):
src = b"".join([int.to_bytes(val, 4, 'little') for val in self.g_CFG_RANDOM_PATTERN])
buf2 = self.sej_aes_hw_internal(src, encrypt=False, attr=attr, sej_param=sej_param)
buf2 = self.sej_aes_hw_internal(src, encrypt=False, attr=attr, sej_param=sej_param, legacy=legacyxor)
attr = attr & 0xFFFFFFFA | 4
else:
self.sst_init(attr=attr, iv=_iv, keylen=key.key_len, mparam=sej_param, key=key.key)
buf2 = self.sej_aes_hw_internal(buf, encrypt=encrypt, attr=attr, sej_param=sej_param, legacy=False)
buf2 = self.sej_aes_hw_internal(buf, encrypt=encrypt, attr=attr, sej_param=sej_param, legacy=legacyxor)
return buf2
def sej_terminate(self):
@ -557,7 +557,7 @@ class Sej(metaclass=LogBase):
if legacy:
self.reg.HACC_UNK |= 2
# clear HACC_ASRC/HACC_ACFG/HACC_AOUT
self.reg.HACC_ACON2 = 0x40000000 | self.HACC_AES_CLR
self.reg.HACC_ACON2 |= 0x40000000
i = 0
while i < 20:
if self.reg.HACC_ACON2 > 0x80000000:
@ -598,12 +598,12 @@ class Sej(metaclass=LogBase):
self.reg.HACC_ACONK = 0
return acon_setting
def hw_aes128_cbc_encrypt(self, buf, encrypt=True, iv=None):
def hw_aes128_cbc_encrypt(self, buf, encrypt=True, iv=None, legacy=False):
if iv is None:
iv = self.g_HACC_CFG_1
self.tz_pre_init()
self.info("HACC init")
self.SEJ_V3_Init(ben=encrypt, iv=iv)
self.SEJ_V3_Init(ben=encrypt, iv=iv, legacy=legacy)
self.info("HACC run")
buf2 = self.sej_run(buf)
self.info("HACC terminate")
@ -693,8 +693,8 @@ class Sej(metaclass=LogBase):
break
return data
def sej_sec_cfg_hw(self, data, encrypt=True):
if encrypt:
def sej_sec_cfg_hw(self, data, encrypt=True, noxor=False):
if encrypt and not noxor:
data = self.xor_data(bytearray(data))
self.info("HACC init")
self.SEJ_V3_Init(ben=encrypt, iv=self.g_HACC_CFG_1, legacy=True)
@ -702,12 +702,12 @@ class Sej(metaclass=LogBase):
dec = self.sej_run(data)
self.info("HACC terminate")
self.sej_terminate()
if not encrypt:
if not encrypt and not noxor:
dec = self.xor_data(dec)
return dec
def sej_sec_cfg_hw_V3(self, data, encrypt=True):
return self.hw_aes128_cbc_encrypt(buf=data, encrypt=encrypt)
def sej_sec_cfg_hw_V3(self, data, encrypt=True, legacy=False):
return self.hw_aes128_cbc_encrypt(buf=data, encrypt=encrypt, legacy=legacy)
# seclib_get_msg_auth_key
def generate_rpmb(self, meid, otp, derivedlen=32):
@ -782,7 +782,7 @@ class Sej(metaclass=LogBase):
self.sej_terminate()
return dec
def generate_hw_meta(self, otp=None, encrypt=False, data=b""):
def generate_hw_meta(self, otp=None, encrypt=False, data=b"", legacy=False):
"""
WR8 mt65
LR9 CRC RC4 AES128-CBC SBC=OFF
@ -800,7 +800,7 @@ class Sej(metaclass=LogBase):
iv = [seed, (~seed) & 0xFFFFFFFF, (((seed >> 16) | (seed << 16)) & 0xFFFFFFFF),
(~((seed >> 16) | (seed << 16)) & 0xFFFFFFFF)]
self.info("HACC init")
self.SEJ_V3_Init(ben=encrypt, iv=iv)
self.SEJ_V3_Init(ben=encrypt, iv=iv, legacy=legacy)
self.info("HACC run")
dec = self.sej_run(data)
self.info("HACC terminate")

View file

@ -60,7 +60,12 @@ class SecCfgV4(metaclass=LogBase):
if _hash == dec_hash:
self.hwtype = "V3"
else:
return False
dec_hash = self.hwc.sej.sej_sec_cfg_hw_V3(self.hash, False, legacy=True)
if _hash == dec_hash:
self.hwtype = "V4"
else:
return False
"""
LKS_DEFAULT = 0x01
LKS_MP_DEFAULT = 0x02
@ -91,11 +96,13 @@ class SecCfgV4(metaclass=LogBase):
dec_hash = hashlib.sha256(seccfg_data).digest()
enc_hash = b""
if self.hwtype == "SW":
enc_hash = self.hwc.sej.sej_sec_cfg_sw(dec_hash, True)
enc_hash = self.hwc.sej.sej_sec_cfg_sw(dec_hash, encrypt=True)
elif self.hwtype == "V2":
enc_hash = self.hwc.sej.sej_sec_cfg_hw(dec_hash, True)
enc_hash = self.hwc.sej.sej_sec_cfg_hw(dec_hash, encrypt=True)
elif self.hwtype == "V3":
enc_hash = self.hwc.sej.sej_sec_cfg_hw_V3(dec_hash, True)
enc_hash = self.hwc.sej.sej_sec_cfg_hw_V3(dec_hash, encrypt=True)
elif self.hwtype == "V4":
enc_hash = self.hwc.sej.sej_sec_cfg_hw_V3(dec_hash, encrypt=True, legacy=True)
indata = seccfg_data + enc_hash
while len(indata) % 0x200 != 0:
indata += b"\x00"
@ -199,14 +206,18 @@ class SecCfgV3(metaclass=LogBase):
if self.magic != 0x4D4D4D4D or self.endflag != 0x45454545:
self.error("Unknown V3 seccfg structure !")
return False
err = self.hwc.sej.sej_sec_cfg_sw(self.data, False)
err = self.hwc.sej.sej_sec_cfg_sw(self.data, encrypt=False)
if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
err = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, False)
err = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, encrypt=False)
if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
err = self.hwc.sej.sej_sec_cfg_hw(self.data, False)
err = self.hwc.sej.sej_sec_cfg_hw(self.data, encrypt=False)
if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
self.error("Unknown V3 seccfg encryption !")
return False
err = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, encrypt=False, legacy=True)
if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
self.error("Unknown V3 seccfg encryption !")
return False
else:
self.hwtype = "V4"
else:
self.hwtype = "V3"
else:
@ -267,11 +278,13 @@ class SecCfgV3(metaclass=LogBase):
ed.write(self.seccfg_ext)
indata = ed.getbuffer()
if self.hwtype == "SW":
indata = self.hwc.sej.sej_sec_cfg_sw(indata, True)
indata = self.hwc.sej.sej_sec_cfg_sw(indata, encrypt=True)
elif self.hwtype == "V2":
indata = self.hwc.sej.sej_sec_cfg_hw(indata, True)
indata = self.hwc.sej.sej_sec_cfg_hw(indata, encrypt=True)
elif self.hwtype == "V3":
indata = self.hwc.sej.sej_sec_cfg_hw_V3(indata, True)
indata = self.hwc.sej.sej_sec_cfg_hw_V3(indata, encrypt=True)
elif self.hwtype == "V4":
indata = self.hwc.sej.sej_sec_cfg_hw_V3(indata, encrypt=True, legacy=True)
else:
return False, "Unknown error"
wf.write(indata)
@ -297,7 +310,7 @@ if __name__ == "__main__":
sej_base = None
v3 = SecCfgV3(hwc, MTK)
v3.parse(data)
ret, newdata = v3.create("lock")
v4 = SecCfgV4(hwc, MTK)
v4.parse(data)
ret, newdata = v4.create("lock")
print(newdata.hex())

View file

@ -42,6 +42,13 @@ class ArgHandler(metaclass=LogBase):
config.pid = getint(args.pid)
except AttributeError:
pass
config.stock = True
try:
if args.stock is not None:
config.stock = args.stock
except AttributeError:
pass
config.reconnect = True
try:
if args.noreconnect is not None:

View file

@ -82,8 +82,8 @@ class PLTools(metaclass=LogBase):
return True
elif response_ack == b"\xc1\xc2\xc3\xc4":
if "preloader" in rf.name:
ack = self.mtk.port.usbread(4)
if ack == b"\xC0\xC0\xC0\xC0":
rack = self.mtk.port.usbread(4)
if rack == b"\xC0\xC0\xC0\xC0":
with open("preloader.bin", 'wb') as wf:
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
for pos in range(0, 0x40000, 64):

View file

@ -1115,7 +1115,7 @@ hwconfig = {
socid_addr=0x102BA8,
efuse_addr=0x11cb0000,
damode=DAmodes.XFLASH,
dacode=0x1066,
dacode=0x6781,
name="MT6781",
description="Helio G96",
loader="mt6781_payload.bin"
@ -1471,7 +1471,7 @@ hwconfig = {
damode=DAmodes.XML,
dacode=0x1172,
name="MT6895",
description="Dimensity 8100"
description="Dimensity 8200"
# loader="mt6893_payload.bin"
),
# MT6789 Oppo Realme 10 / Gigaset GX4

View file

@ -69,6 +69,7 @@ class MtkConfig(metaclass=LogBase):
self.sram = None
self.dram = None
self.otp = None
self.stock = False
if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename)

View file

@ -13,7 +13,7 @@ maintainers = [
]
readme = "README.md"
license = {file = "LICENSE"}
version = "2.0.1"
version = "2.0.2"
requires-python = ">= 3.8"
dependencies = [
"pyusb",