mirror of
https://github.com/bkerler/mtkclient.git
synced 2024-11-14 19:25:05 -05:00
Merge pull request #696 from bkerler/newcrypto
Add full lock V3 support
This commit is contained in:
commit
305903c64d
10 changed files with 539 additions and 297 deletions
|
@ -2,6 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# (c) B.Kerler 2018-2021 GPLv3 License
|
# (c) B.Kerler 2018-2021 GPLv3 License
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
from mtkclient.Library.utils import LogBase, logsetup
|
from mtkclient.Library.utils import LogBase, logsetup
|
||||||
from mtkclient.Library.hwcrypto_gcpu import GCpu
|
from mtkclient.Library.hwcrypto_gcpu import GCpu
|
||||||
|
@ -62,12 +63,17 @@ class hwcrypto(metaclass=LogBase):
|
||||||
if mode == "cbc":
|
if mode == "cbc":
|
||||||
return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=True)
|
return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=True)
|
||||||
elif mode == "sst":
|
elif mode == "sst":
|
||||||
return self.sej.hw_aes128_sst_encrypt(buf=data, encrypt=True)
|
data2=self.sej.generate_hw_meta(encrypt=True,data=data)
|
||||||
|
data3=self.sej.SST_Secure_Algo_With_Level(buf=data, encrypt=True)
|
||||||
|
print(data2.hex())
|
||||||
|
print(data3.hex())
|
||||||
|
sys.stdout.flush()
|
||||||
|
return data3
|
||||||
else:
|
else:
|
||||||
if mode == "cbc":
|
if mode == "cbc":
|
||||||
return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=False)
|
return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=False)
|
||||||
elif mode == "sst":
|
elif mode == "sst":
|
||||||
return self.sej.hw_aes128_sst_encrypt(buf=data, encrypt=False)
|
return self.sej.SST_Secure_Algo_With_Level(buf=data, encrypt=False)
|
||||||
if mode == "rpmb":
|
if mode == "rpmb":
|
||||||
return self.sej.generate_rpmb(meid=data, otp=otp)
|
return self.sej.generate_rpmb(meid=data, otp=otp)
|
||||||
elif mode == "mtee":
|
elif mode == "mtee":
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
import logging, os
|
import logging, os
|
||||||
from struct import pack, unpack
|
from struct import pack, unpack
|
||||||
from mtkclient.Library.utils import LogBase
|
from mtkclient.Library.utils import LogBase
|
||||||
|
from mtkclient.Library.cryptutils import cryptutils
|
||||||
|
|
||||||
|
CustomSeed = bytes.fromhex("00be13bb95e218b53d07a089cb935255294f70d4088f3930350bc636cc49c9025ece7a62c292853ef55b23a6ef7b7464c7f3f2a74ae919416d6b4d9c1d6809655dd82d43d65999cf041a386e1c0f1e58849d8ed09ef07e6a9f0d7d3b8dad6cbae4668a2fd53776c3d26f88b0bf617c8112b8b1a871d322d9513491e07396e1638090055f4b8b9aa2f4ec24ebaeb917e81f468783ea771b278614cd5779a3ca50df5cc5af0edc332e2b69b2b42154bcfffd0af13ce5a467abb7fb107fe794f928da44b6db7215aa53bd0398e3403126fad1f7de2a56edfe474c5a06f8dd9bc0b3422c45a9a132e64e48fcacf63f787560c4c89701d7c125118c20a5ee820c3a16")
|
||||||
|
|
||||||
CustomSeed = bytearray(b"12abcdef")
|
|
||||||
|
|
||||||
# SEJ = Security Engine for JTAG protection
|
# SEJ = Security Engine for JTAG protection
|
||||||
|
|
||||||
|
@ -16,6 +18,13 @@ def bytes_to_dwords(buf):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
class symkey:
|
||||||
|
key = None
|
||||||
|
key_len = 0x10
|
||||||
|
mode = 1
|
||||||
|
iv = None
|
||||||
|
|
||||||
|
|
||||||
AES_CBC_MODE = 1
|
AES_CBC_MODE = 1
|
||||||
AES_SW_KEY = 0
|
AES_SW_KEY = 0
|
||||||
AES_HW_KEY = 1
|
AES_HW_KEY = 1
|
||||||
|
@ -260,95 +269,6 @@ class sej(metaclass=LogBase):
|
||||||
# self.crypto_secure(1)
|
# self.crypto_secure(1)
|
||||||
return
|
return
|
||||||
|
|
||||||
def SEJ_Init_MTEE(self, encrypt=True, iv=None):
|
|
||||||
if iv is None:
|
|
||||||
iv = self.g_HACC_CFG_MTEE
|
|
||||||
acon_setting = self.HACC_AES_CHG_BO_OFF | self.HACC_AES_CBC | self.HACC_AES_128
|
|
||||||
if encrypt:
|
|
||||||
acon_setting |= self.HACC_AES_ENC
|
|
||||||
else:
|
|
||||||
acon_setting |= self.HACC_AES_DEC
|
|
||||||
|
|
||||||
# clear key
|
|
||||||
self.reg.HACC_AKEY0 = 0
|
|
||||||
self.reg.HACC_AKEY1 = 0
|
|
||||||
self.reg.HACC_AKEY2 = 0
|
|
||||||
self.reg.HACC_AKEY3 = 0
|
|
||||||
self.reg.HACC_AKEY4 = 0
|
|
||||||
self.reg.HACC_AKEY5 = 0
|
|
||||||
self.reg.HACC_AKEY6 = 0
|
|
||||||
self.reg.HACC_AKEY7 = 0
|
|
||||||
|
|
||||||
self.reg.HACC_ACON2 = self.HACC_AES_CBC
|
|
||||||
self.reg.HACC_ACONK = self.HACC_AES_BK2C
|
|
||||||
self.reg.HACC_ACONK |= 0x100
|
|
||||||
self.reg.HACC_ACON = self.HACC_AES_CLR
|
|
||||||
|
|
||||||
self.reg.HACC_ACFG0 = iv[0]
|
|
||||||
self.reg.HACC_ACFG1 = iv[1]
|
|
||||||
self.reg.HACC_ACFG2 = iv[2]
|
|
||||||
self.reg.HACC_ACFG3 = iv[3]
|
|
||||||
|
|
||||||
for val in [[0x2d44bb70,0xa744d227,0xd0a9864b,0x83ffc244],
|
|
||||||
[0x7ec8266b,0x43e80fb2,0x1a6348a,0x2067f9a0],
|
|
||||||
[0x54536405,0xd546a6b1,0x1cc3ec3a,0xde377a83]]:
|
|
||||||
self.reg.HACC_ASRC0 = val[0]
|
|
||||||
self.reg.HACC_ASRC1 = val[1]
|
|
||||||
self.reg.HACC_ASRC2 = val[2]
|
|
||||||
self.reg.HACC_ASRC3 = val[3]
|
|
||||||
self.reg.HACC_ACON2 = self.HACC_AES_START
|
|
||||||
i = 0
|
|
||||||
while i < 20:
|
|
||||||
if self.reg.HACC_ACON2 & self.HACC_AES_RDY != 0:
|
|
||||||
break
|
|
||||||
i += 1
|
|
||||||
if i == 20:
|
|
||||||
self.error("SEJ Hardware seems not to be configured correctly. Results may be wrong.")
|
|
||||||
|
|
||||||
self.reg.HACC_ACON2 = self.HACC_AES_CBC
|
|
||||||
self.reg.HACC_ACFG0 = iv[0]
|
|
||||||
self.reg.HACC_ACFG1 = iv[1]
|
|
||||||
self.reg.HACC_ACFG2 = iv[2]
|
|
||||||
self.reg.HACC_ACFG3 = iv[3]
|
|
||||||
self.reg.HACC_ACON = acon_setting
|
|
||||||
self.reg.HACC_ACONK = 0x0
|
|
||||||
|
|
||||||
def SEJ_Init(self, encrypt=True, iv=None):
|
|
||||||
if iv is None:
|
|
||||||
iv = self.g_HACC_CFG_1
|
|
||||||
acon_setting = self.HACC_AES_CHG_BO_OFF | self.HACC_AES_CBC | self.HACC_AES_128
|
|
||||||
if encrypt:
|
|
||||||
acon_setting |= self.HACC_AES_ENC
|
|
||||||
else:
|
|
||||||
acon_setting |= self.HACC_AES_DEC
|
|
||||||
|
|
||||||
# clear key
|
|
||||||
self.reg.HACC_AKEY0 = 0
|
|
||||||
self.reg.HACC_AKEY1 = 0
|
|
||||||
self.reg.HACC_AKEY2 = 0
|
|
||||||
self.reg.HACC_AKEY3 = 0
|
|
||||||
self.reg.HACC_AKEY4 = 0
|
|
||||||
self.reg.HACC_AKEY5 = 0
|
|
||||||
self.reg.HACC_AKEY6 = 0
|
|
||||||
self.reg.HACC_AKEY7 = 0
|
|
||||||
self.reg.HACC_ACFG0 = iv[0] # g_AC_CFG
|
|
||||||
self.reg.HACC_ACFG1 = iv[1]
|
|
||||||
self.reg.HACC_ACFG2 = iv[2]
|
|
||||||
self.reg.HACC_ACFG3 = iv[3]
|
|
||||||
self.reg.HACC_UNK |= 2
|
|
||||||
|
|
||||||
# clear HACC_ASRC/HACC_ACFG/HACC_AOUT
|
|
||||||
self.reg.HACC_ACON2 = 0x40000000 | self.HACC_AES_CLR
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if self.reg.HACC_ACON2 > 0x80000000:
|
|
||||||
break
|
|
||||||
|
|
||||||
self.reg.HACC_UNK &= 0xFFFFFFFE
|
|
||||||
self.reg.HACC_ACONK = self.HACC_AES_BK2C
|
|
||||||
self.reg.HACC_ACON = acon_setting
|
|
||||||
return acon_setting
|
|
||||||
|
|
||||||
def SEJ_Run(self, data):
|
def SEJ_Run(self, data):
|
||||||
pdst = bytearray()
|
pdst = bytearray()
|
||||||
psrc = bytes_to_dwords(data)
|
psrc = bytes_to_dwords(data)
|
||||||
|
@ -374,6 +294,155 @@ class sej(metaclass=LogBase):
|
||||||
pos += 4
|
pos += 4
|
||||||
return pdst
|
return pdst
|
||||||
|
|
||||||
|
def SEJ_AES_HW_Init(self, attr, key: symkey, sej_param=3):
|
||||||
|
# key.mode 0 = ECB
|
||||||
|
# key.mode 1 = CBC
|
||||||
|
if key.key is None:
|
||||||
|
key.key = b""
|
||||||
|
if attr << 31 and sej_param << 31:
|
||||||
|
if key.key is None:
|
||||||
|
return 0x6001
|
||||||
|
if key.iv is None and key.mode == 1:
|
||||||
|
return 0x6002
|
||||||
|
|
||||||
|
self.reg.HACC_SECINIT0 = 1
|
||||||
|
if attr & 1 == 0 or sej_param & 1 != 0:
|
||||||
|
acon_setting = self.HACC_AES_128
|
||||||
|
elif len(key.key) == 0x18:
|
||||||
|
acon_setting = self.HACC_AES_192
|
||||||
|
elif len(key.key) == 0x20:
|
||||||
|
acon_setting = self.HACC_AES_256
|
||||||
|
else:
|
||||||
|
acon_setting = self.HACC_AES_192
|
||||||
|
if key.mode:
|
||||||
|
acon_setting |= self.HACC_AES_CBC
|
||||||
|
self.reg.HACC_ACON = acon_setting
|
||||||
|
"""
|
||||||
|
if m_src_addr<<30 or m_dst_addr << 30:
|
||||||
|
return 0x6007
|
||||||
|
if not m_src_len:
|
||||||
|
return 0x600A
|
||||||
|
if m_src_len != m_dst_len:
|
||||||
|
return 0x6000
|
||||||
|
if m_src_len << 29:
|
||||||
|
return 0x6032
|
||||||
|
memset(outbuf,0,0x20)
|
||||||
|
if attr&4 == 0:
|
||||||
|
CP_Power_On_SEJ_HW(1)
|
||||||
|
"""
|
||||||
|
|
||||||
|
if attr & 1 != 0:
|
||||||
|
self.reg.HACC_AKEY0 = 0
|
||||||
|
self.reg.HACC_AKEY1 = 0
|
||||||
|
self.reg.HACC_AKEY2 = 0
|
||||||
|
self.reg.HACC_AKEY3 = 0
|
||||||
|
self.reg.HACC_AKEY4 = 0
|
||||||
|
self.reg.HACC_AKEY5 = 0
|
||||||
|
self.reg.HACC_AKEY6 = 0
|
||||||
|
self.reg.HACC_AKEY7 = 0
|
||||||
|
if sej_param & 1 != 0:
|
||||||
|
self.reg.HACC_ACONK = self.HACC_AES_BK2C
|
||||||
|
else:
|
||||||
|
keydata = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
# toDo: Is this valid ?
|
||||||
|
for i in range(0, len(key.key), 4):
|
||||||
|
keydata[i // 4] = unpack(">I", key.key[i:i + 4])[0]
|
||||||
|
if len(key.key) >= 8:
|
||||||
|
self.reg.HACC_AKEY0 = keydata[0]
|
||||||
|
self.reg.HACC_AKEY1 = keydata[1]
|
||||||
|
if len(key.key) >= 16:
|
||||||
|
self.reg.HACC_AKEY2 = keydata[2]
|
||||||
|
self.reg.HACC_AKEY3 = keydata[3]
|
||||||
|
if len(key.key) >= 24:
|
||||||
|
self.reg.HACC_AKEY4 = keydata[4]
|
||||||
|
self.reg.HACC_AKEY5 = keydata[5]
|
||||||
|
if len(key.key) >= 32:
|
||||||
|
self.reg.HACC_AKEY6 = keydata[6]
|
||||||
|
self.reg.HACC_AKEY7 = keydata[7]
|
||||||
|
if attr & 2 != 0:
|
||||||
|
self.reg.HACC_ACON2 = self.HACC_AES_CLR
|
||||||
|
self.reg.HACC_ACFG0 = key.iv[0] # g_AC_CFG
|
||||||
|
self.reg.HACC_ACFG1 = key.iv[1]
|
||||||
|
self.reg.HACC_ACFG2 = key.iv[2]
|
||||||
|
self.reg.HACC_ACFG3 = key.iv[3]
|
||||||
|
|
||||||
|
def SEJ_AES_HW_Internal(self, data, encrypt, attr, sej_param, legacy=True):
|
||||||
|
if encrypt:
|
||||||
|
self.reg.HACC_ACON |= 1
|
||||||
|
if legacy:
|
||||||
|
if (attr & 8) != 0 and (sej_param & 2) != 0:
|
||||||
|
self.reg.HACC_ACONK |= self.HACC_AES_R2K
|
||||||
|
else:
|
||||||
|
self.reg.HACC_ACONK &= 0xFFFFFEFF
|
||||||
|
pdst = bytearray()
|
||||||
|
psrc = bytes_to_dwords(data)
|
||||||
|
plen = len(psrc)
|
||||||
|
pos = 0
|
||||||
|
for i in range(plen // 4):
|
||||||
|
self.reg.HACC_ASRC0 = psrc[pos + 0]
|
||||||
|
self.reg.HACC_ASRC1 = psrc[pos + 1]
|
||||||
|
self.reg.HACC_ASRC2 = psrc[pos + 2]
|
||||||
|
self.reg.HACC_ASRC3 = psrc[pos + 3]
|
||||||
|
self.reg.HACC_ACON2 = self.HACC_AES_START
|
||||||
|
i = 0
|
||||||
|
while i < 20:
|
||||||
|
if self.reg.HACC_ACON2 & self.HACC_AES_RDY != 0:
|
||||||
|
break
|
||||||
|
i += 1
|
||||||
|
if i == 20:
|
||||||
|
self.error("SEJ Hardware seems not to be configured correctly. Results may be wrong.")
|
||||||
|
pdst.extend(pack("<I", self.reg.HACC_AOUT0))
|
||||||
|
pdst.extend(pack("<I", self.reg.HACC_AOUT1))
|
||||||
|
pdst.extend(pack("<I", self.reg.HACC_AOUT2))
|
||||||
|
pdst.extend(pack("<I", self.reg.HACC_AOUT3))
|
||||||
|
pos += 4
|
||||||
|
if legacy:
|
||||||
|
if (attr & 8) != 0 and (sej_param & 2) == 0:
|
||||||
|
# Key_Feedback_XOR_Handler
|
||||||
|
keylen = 0x20
|
||||||
|
for pos in range(keylen // 4):
|
||||||
|
self.reg.HACC_AKEY0[pos] = pdst[pos] ^ self.reg.HACC_AKEY0[pos]
|
||||||
|
return pdst
|
||||||
|
|
||||||
|
def SST_Secure_Algo_With_Level(self, buf, encrypt=True, aes_top_legacy=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)]
|
||||||
|
key = symkey()
|
||||||
|
key.key = None
|
||||||
|
key.key_len = 0x10
|
||||||
|
key.mode = 1 # CBC
|
||||||
|
key.iv = iv
|
||||||
|
if aes_top_legacy:
|
||||||
|
sej_param = 3
|
||||||
|
else:
|
||||||
|
sej_param = 5
|
||||||
|
# Cipher Internal
|
||||||
|
if sej_param & 0xC != 0:
|
||||||
|
if sej_param & 4 != 0:
|
||||||
|
# sej_param 5
|
||||||
|
attr = 0x3A
|
||||||
|
else:
|
||||||
|
attr = 0x32
|
||||||
|
flag = 1
|
||||||
|
else:
|
||||||
|
# aes_top_legacy
|
||||||
|
attr = 0x33
|
||||||
|
flag = 0
|
||||||
|
metaflag = not flag
|
||||||
|
# CS_MTK_Cipher_Internal
|
||||||
|
if metaflag:
|
||||||
|
# length=0x10
|
||||||
|
attr = 0x5B
|
||||||
|
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)
|
||||||
|
attr = attr & 0xFFFFFFFA | 4
|
||||||
|
self.SEJ_AES_HW_Init(attr, key, sej_param)
|
||||||
|
buf2 = self.SEJ_AES_HW_Internal(buf, encrypt=encrypt, attr=attr, sej_param=sej_param)
|
||||||
|
return buf2
|
||||||
|
|
||||||
def SEJ_Terminate(self):
|
def SEJ_Terminate(self):
|
||||||
self.reg.HACC_ACON2 = self.HACC_AES_CLR
|
self.reg.HACC_ACON2 = self.HACC_AES_CLR
|
||||||
self.reg.HACC_AKEY0 = 0
|
self.reg.HACC_AKEY0 = 0
|
||||||
|
@ -385,10 +454,10 @@ class sej(metaclass=LogBase):
|
||||||
self.reg.HACC_AKEY6 = 0
|
self.reg.HACC_AKEY6 = 0
|
||||||
self.reg.HACC_AKEY7 = 0
|
self.reg.HACC_AKEY7 = 0
|
||||||
|
|
||||||
def SEJ_V3_Init(self, ben=True, iv=None):
|
def SEJ_V3_Init(self, ben=True, iv=None, legacy=False):
|
||||||
if iv is None:
|
acon_setting = self.HACC_AES_CHG_BO_OFF | self.HACC_AES_128
|
||||||
iv = self.g_HACC_CFG_1
|
if iv is not None:
|
||||||
acon_setting = self.HACC_AES_CHG_BO_OFF | self.HACC_AES_CBC | self.HACC_AES_128
|
acon_setting |= self.HACC_AES_CBC
|
||||||
if ben:
|
if ben:
|
||||||
acon_setting |= self.HACC_AES_ENC
|
acon_setting |= self.HACC_AES_ENC
|
||||||
else:
|
else:
|
||||||
|
@ -413,34 +482,52 @@ class sej(metaclass=LogBase):
|
||||||
|
|
||||||
# clear HACC_ASRC/HACC_ACFG/HACC_AOUT
|
# clear HACC_ASRC/HACC_ACFG/HACC_AOUT
|
||||||
self.reg.HACC_ACON2 = self.HACC_AES_CLR # 0x08
|
self.reg.HACC_ACON2 = self.HACC_AES_CLR # 0x08
|
||||||
self.reg.HACC_UNK = 1
|
#self.reg.HACC_UNK = 1
|
||||||
self.reg.HACC_ACFG0 = iv[0] # g_AC_CFG
|
self.reg.HACC_ACFG0 = iv[0] # g_AC_CFG
|
||||||
self.reg.HACC_ACFG1 = iv[1]
|
self.reg.HACC_ACFG1 = iv[1]
|
||||||
self.reg.HACC_ACFG2 = iv[2]
|
self.reg.HACC_ACFG2 = iv[2]
|
||||||
self.reg.HACC_ACFG3 = iv[3]
|
self.reg.HACC_ACFG3 = iv[3]
|
||||||
|
|
||||||
# encrypt fix pattern 3 rounds to generate a pattern from HUID/HUK
|
if legacy:
|
||||||
for i in range(0, 3):
|
self.reg.HACC_UNK |= 2
|
||||||
pos = i * 4
|
# clear HACC_ASRC/HACC_ACFG/HACC_AOUT
|
||||||
self.reg.HACC_ASRC0 = self.g_CFG_RANDOM_PATTERN[pos]
|
self.reg.HACC_ACON2 = 0x40000000 | self.HACC_AES_CLR
|
||||||
self.reg.HACC_ASRC1 = self.g_CFG_RANDOM_PATTERN[pos + 1]
|
while True:
|
||||||
self.reg.HACC_ASRC2 = self.g_CFG_RANDOM_PATTERN[pos + 2]
|
if self.reg.HACC_ACON2 > 0x80000000:
|
||||||
self.reg.HACC_ASRC3 = self.g_CFG_RANDOM_PATTERN[pos + 3]
|
|
||||||
self.reg.HACC_ACON2 = self.HACC_AES_START
|
|
||||||
i = 0
|
|
||||||
while i < 20:
|
|
||||||
if self.reg.HACC_ACON2 & self.HACC_AES_RDY != 0:
|
|
||||||
break
|
break
|
||||||
i += 1
|
|
||||||
if i == 20:
|
self.reg.HACC_UNK &= 0xFFFFFFFE
|
||||||
self.error("SEJ Hardware seems not to be configured correctly. Results may be wrong.")
|
self.reg.HACC_ACONK = self.HACC_AES_BK2C
|
||||||
self.reg.HACC_ACON2 = self.HACC_AES_CLR
|
self.reg.HACC_ACON = acon_setting
|
||||||
self.reg.HACC_ACFG0 = iv[0]
|
else:
|
||||||
self.reg.HACC_ACFG1 = iv[1]
|
# The reg below needed for mtee ?
|
||||||
self.reg.HACC_ACFG2 = iv[2]
|
self.reg.HACC_UNK = 1
|
||||||
self.reg.HACC_ACFG3 = iv[3]
|
|
||||||
self.reg.HACC_ACON = acon_setting
|
# encrypt fix pattern 3 rounds to generate a pattern from HUID/HUK
|
||||||
self.reg.HACC_ACONK = 0
|
for i in range(0, 3):
|
||||||
|
pos = i * 4
|
||||||
|
self.reg.HACC_ASRC0 = self.g_CFG_RANDOM_PATTERN[pos]
|
||||||
|
self.reg.HACC_ASRC1 = self.g_CFG_RANDOM_PATTERN[pos + 1]
|
||||||
|
self.reg.HACC_ASRC2 = self.g_CFG_RANDOM_PATTERN[pos + 2]
|
||||||
|
self.reg.HACC_ASRC3 = self.g_CFG_RANDOM_PATTERN[pos + 3]
|
||||||
|
self.reg.HACC_ACON2 = self.HACC_AES_START
|
||||||
|
i = 0
|
||||||
|
while i < 20:
|
||||||
|
if self.reg.HACC_ACON2 & self.HACC_AES_RDY != 0:
|
||||||
|
break
|
||||||
|
i += 1
|
||||||
|
if i == 20:
|
||||||
|
self.error("SEJ Hardware seems not to be configured correctly. Results may be wrong.")
|
||||||
|
|
||||||
|
self.reg.HACC_ACON2 = self.HACC_AES_CLR
|
||||||
|
|
||||||
|
self.reg.HACC_ACFG0 = iv[0]
|
||||||
|
self.reg.HACC_ACFG1 = iv[1]
|
||||||
|
self.reg.HACC_ACFG2 = iv[2]
|
||||||
|
self.reg.HACC_ACFG3 = iv[3]
|
||||||
|
self.reg.HACC_ACON = acon_setting
|
||||||
|
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):
|
||||||
if iv is None:
|
if iv is None:
|
||||||
|
@ -454,19 +541,6 @@ class sej(metaclass=LogBase):
|
||||||
self.SEJ_Terminate()
|
self.SEJ_Terminate()
|
||||||
return buf2
|
return buf2
|
||||||
|
|
||||||
def hw_aes128_sst_encrypt(self, buf, encrypt=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)]
|
|
||||||
|
|
||||||
self.tz_pre_init()
|
|
||||||
self.info("HACC init")
|
|
||||||
self.SEJ_Init(encrypt=encrypt, iv=iv)
|
|
||||||
self.info("HACC run")
|
|
||||||
buf2 = self.SEJ_Run(buf)
|
|
||||||
self.info("HACC terminate")
|
|
||||||
self.SEJ_Terminate()
|
|
||||||
return buf2
|
|
||||||
|
|
||||||
def sej_set_otp(self, data):
|
def sej_set_otp(self, data):
|
||||||
pd = bytes_to_dwords(data)
|
pd = bytes_to_dwords(data)
|
||||||
self.reg.HACC_SW_OTP0 = pd[0]
|
self.reg.HACC_SW_OTP0 = pd[0]
|
||||||
|
@ -526,10 +600,18 @@ class sej(metaclass=LogBase):
|
||||||
self.sej_set_key(AES_HW_WRAP_KEY, AES_KEY_256, hw_key)
|
self.sej_set_key(AES_HW_WRAP_KEY, AES_KEY_256, hw_key)
|
||||||
|
|
||||||
def sej_sec_cfg_sw(self, data, encrypt=True):
|
def sej_sec_cfg_sw(self, data, encrypt=True):
|
||||||
|
"""
|
||||||
|
Left for reference - hw implementation
|
||||||
|
--------------------------------------
|
||||||
self.sej_set_mode(AES_CBC_MODE)
|
self.sej_set_mode(AES_CBC_MODE)
|
||||||
self.sej_set_key(AES_SW_KEY, AES_KEY_256, b"1A52A367CB12C458965D32CD874B36B2")
|
self.sej_set_key(AES_SW_KEY, AES_KEY_256, b"1A52A367CB12C458965D32CD874B36B2")
|
||||||
iv = bytes.fromhex("57325A5A125497661254976657325A5A")
|
iv = bytes.fromhex("57325A5A125497661254976657325A5A")
|
||||||
res = self.sej_do_aes(encrypt, iv, data, len(data))
|
res = self.sej_do_aes(encrypt, iv, data, len(data))
|
||||||
|
"""
|
||||||
|
ctx = cryptutils.aes()
|
||||||
|
res = ctx.aes_cbc(key=b"25A1763A21BC854CD569DC23B4782B63",
|
||||||
|
iv=bytes.fromhex("57325A5A125497661254976657325A5A"), data=data,
|
||||||
|
decrypt=not encrypt)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def xor_data(self, data):
|
def xor_data(self, data):
|
||||||
|
@ -545,7 +627,7 @@ class sej(metaclass=LogBase):
|
||||||
if encrypt:
|
if encrypt:
|
||||||
data = self.xor_data(bytearray(data))
|
data = self.xor_data(bytearray(data))
|
||||||
self.info("HACC init")
|
self.info("HACC init")
|
||||||
self.SEJ_Init(encrypt=encrypt)
|
self.SEJ_V3_Init(ben=encrypt,iv=self.g_HACC_CFG_1,legacy=True)
|
||||||
self.info("HACC run")
|
self.info("HACC run")
|
||||||
dec = self.SEJ_Run(data)
|
dec = self.SEJ_Run(data)
|
||||||
self.info("HACC terminate")
|
self.info("HACC terminate")
|
||||||
|
@ -623,9 +705,23 @@ class sej(metaclass=LogBase):
|
||||||
if otp is not None:
|
if otp is not None:
|
||||||
self.sej_set_otp(otp)
|
self.sej_set_otp(otp)
|
||||||
self.info("HACC init")
|
self.info("HACC init")
|
||||||
self.SEJ_Init_MTEE(encrypt=True)
|
self.SEJ_V3_Init(ben=True, iv=self.g_HACC_CFG_MTEE)
|
||||||
self.info("HACC run")
|
self.info("HACC run")
|
||||||
dec = self.SEJ_Run(bytes.fromhex("7777772E6D6564696174656B2E636F6D30313233343536373839414243444546"))
|
dec = self.SEJ_Run(bytes.fromhex("7777772E6D6564696174656B2E636F6D30313233343536373839414243444546"))
|
||||||
self.info("HACC terminate")
|
self.info("HACC terminate")
|
||||||
self.SEJ_Terminate()
|
self.SEJ_Terminate()
|
||||||
return dec
|
return dec
|
||||||
|
|
||||||
|
def generate_hw_meta(self, otp=None, encrypt=False, data=b""):
|
||||||
|
if otp is not None:
|
||||||
|
self.sej_set_otp(otp)
|
||||||
|
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)]
|
||||||
|
self.info("HACC init")
|
||||||
|
self.SEJ_V3_Init(ben=encrypt, iv=iv)
|
||||||
|
self.info("HACC run")
|
||||||
|
dec = self.SEJ_Run(data)
|
||||||
|
self.info("HACC terminate")
|
||||||
|
self.SEJ_Terminate()
|
||||||
|
return dec
|
|
@ -6,7 +6,7 @@ from mtkclient.config.payloads import pathconfig
|
||||||
from mtkclient.Library.error import ErrorHandler
|
from mtkclient.Library.error import ErrorHandler
|
||||||
from mtkclient.Library.hwcrypto import crypto_setup, hwcrypto
|
from mtkclient.Library.hwcrypto import crypto_setup, hwcrypto
|
||||||
from mtkclient.Library.utils import LogBase, logsetup, find_binary
|
from mtkclient.Library.utils import LogBase, logsetup, find_binary
|
||||||
from mtkclient.Library.seccfg import seccfg
|
from mtkclient.Library.seccfg import seccfgV4, seccfgV3
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
from mtkclient.Library.utils import mtktee
|
from mtkclient.Library.utils import mtktee
|
||||||
import hashlib
|
import hashlib
|
||||||
|
@ -160,105 +160,10 @@ class legacyext(metaclass=LogBase):
|
||||||
setup.writemem = self.writemem
|
setup.writemem = self.writemem
|
||||||
return hwcrypto(setup, self.loglevel, self.config.gui)
|
return hwcrypto(setup, self.loglevel, self.config.gui)
|
||||||
|
|
||||||
def seccfg_custom_V3(self, seccfg_data, lockflag, hwc, partition):
|
|
||||||
|
|
||||||
# enum {
|
|
||||||
ATTR_LOCK = 0x6000
|
|
||||||
ATTR_VERIFIED = 0x6001
|
|
||||||
ATTR_CUSTOM = 0x6002
|
|
||||||
ATTR_MP_DEFAULT = 0x6003
|
|
||||||
ATTR_DEFAULT = 0x33333333
|
|
||||||
ATTR_UNLOCK = 0x44444444
|
|
||||||
# } SECCFG_ATTR;
|
|
||||||
|
|
||||||
magic_number_beg = 0x10
|
|
||||||
magic_number_end = magic_number_beg + 4
|
|
||||||
|
|
||||||
secattr_beg = 0x854
|
|
||||||
|
|
||||||
enc_cfg_sz = 0x1860
|
|
||||||
enc_cfg_beg = 0x2C
|
|
||||||
enc_cfg_end = enc_cfg_sz - 4
|
|
||||||
|
|
||||||
enc_cfg_secattr = secattr_beg - enc_cfg_beg
|
|
||||||
|
|
||||||
if seccfg_data[magic_number_beg : magic_number_end] != pack("<I", 0x4D4D4D4D):
|
|
||||||
return False
|
|
||||||
|
|
||||||
sc_new = seccfg(hwc)
|
|
||||||
self.setotp(hwc)
|
|
||||||
|
|
||||||
enc_data = seccfg_data[enc_cfg_beg : enc_cfg_end]
|
|
||||||
|
|
||||||
self.info("Attempt decrypt current seccfg")
|
|
||||||
data_wr = sc_new.hwc.sej.sej_sec_cfg_hw_V3(enc_data, False)
|
|
||||||
|
|
||||||
|
|
||||||
if lockflag == "lock":
|
|
||||||
_SEC_ATTR_NEW = ATTR_DEFAULT
|
|
||||||
else:
|
|
||||||
_SEC_ATTR_NEW = ATTR_UNLOCK
|
|
||||||
|
|
||||||
|
|
||||||
_SEC_ATTR_CURRENT = data_wr[enc_cfg_secattr : enc_cfg_secattr + 4]
|
|
||||||
_SEC_ATTR_CURRENT = unpack('<I', _SEC_ATTR_CURRENT)[0]
|
|
||||||
|
|
||||||
|
|
||||||
if (lockflag == "lock"
|
|
||||||
and _SEC_ATTR_CURRENT != ATTR_UNLOCK):
|
|
||||||
return False, ("Can't find lock state, current (%#x)" % _SEC_ATTR_CURRENT)
|
|
||||||
elif (lockflag == "unlock"
|
|
||||||
and _SEC_ATTR_CURRENT != ATTR_DEFAULT
|
|
||||||
and _SEC_ATTR_CURRENT != ATTR_MP_DEFAULT
|
|
||||||
and _SEC_ATTR_CURRENT != ATTR_CUSTOM
|
|
||||||
and _SEC_ATTR_CURRENT != ATTR_VERIFIED
|
|
||||||
and _SEC_ATTR_CURRENT != ATTR_LOCK):
|
|
||||||
return False, ("Can't find unlock state, current (%#x)" % _SEC_ATTR_CURRENT)
|
|
||||||
|
|
||||||
|
|
||||||
self.info("Set %s flag" % lockflag)
|
|
||||||
data_wr[enc_cfg_secattr : enc_cfg_secattr + 4] = pack('<I', _SEC_ATTR_NEW)
|
|
||||||
|
|
||||||
self.info("Attempt encrypt new seccfg")
|
|
||||||
enc_data = sc_new.hwc.sej.sej_sec_cfg_hw_V3(data_wr, True)
|
|
||||||
|
|
||||||
# Test new seccfg {
|
|
||||||
self.info("Attempt decrypt new seccfg")
|
|
||||||
data_wr = sc_new.hwc.sej.sej_sec_cfg_hw_V3(enc_data, False)
|
|
||||||
|
|
||||||
if data_wr[enc_cfg_secattr : enc_cfg_secattr + 4] == pack('<I', _SEC_ATTR_NEW):
|
|
||||||
self.info("Test OK. Set %s in new seccfg successfully" % lockflag)
|
|
||||||
else:
|
|
||||||
return False, "Test error. Can't decrypt new seccfg"
|
|
||||||
# }
|
|
||||||
|
|
||||||
seccfg_data[enc_cfg_beg : enc_cfg_end] = enc_data
|
|
||||||
|
|
||||||
# 0x22 is (SECURE_CFG_V3*)->fb_status
|
|
||||||
# 0x23 is (SECURE_CFG_V3*)->dbg_status
|
|
||||||
if lockflag == "lock":
|
|
||||||
seccfg_data[0x22:0x23] = b'\x00'
|
|
||||||
seccfg_data[0x23:0x24] = b'\x01'
|
|
||||||
elif lockflag == "unlock":
|
|
||||||
# seccfg_data[0x22:0x23] = b'\x67'
|
|
||||||
seccfg_data[0x22:0x23] = b'\xF2'
|
|
||||||
seccfg_data[0x23:0x24] = b'\x07'
|
|
||||||
|
|
||||||
enc_writedata = seccfg_data
|
|
||||||
|
|
||||||
|
|
||||||
self.info("Attempt write new seccfg config")
|
|
||||||
if self.legacy.writeflash(addr=partition.sector * self.mtk.daloader.daconfig.pagesize,
|
|
||||||
length=len(enc_writedata),
|
|
||||||
filename=None, wdata=enc_writedata, parttype="user", display=True):
|
|
||||||
return True, "Successfully wrote custom seccfg."
|
|
||||||
return False, "Error on writing custom seccfg config to flash."
|
|
||||||
|
|
||||||
def seccfg(self, lockflag):
|
def seccfg(self, lockflag):
|
||||||
if lockflag not in ["unlock", "lock"]:
|
if lockflag not in ["unlock", "lock"]:
|
||||||
return False, "Valid flags are: unlock, lock"
|
return False, "Valid flags are: unlock, lock"
|
||||||
hwc = self.cryptosetup()
|
hwc = self.cryptosetup()
|
||||||
sc_org = seccfg(hwc)
|
|
||||||
data, guid_gpt = self.legacy.partition.get_gpt(self.mtk.config.gpt_settings, "user")
|
data, guid_gpt = self.legacy.partition.get_gpt(self.mtk.config.gpt_settings, "user")
|
||||||
seccfg_data = None
|
seccfg_data = None
|
||||||
partition = None
|
partition = None
|
||||||
|
@ -272,32 +177,29 @@ class legacyext(metaclass=LogBase):
|
||||||
break
|
break
|
||||||
if seccfg_data is None:
|
if seccfg_data is None:
|
||||||
return False, "Couldn't detect existing seccfg partition. Aborting unlock."
|
return False, "Couldn't detect existing seccfg partition. Aborting unlock."
|
||||||
if seccfg_data[:4] != pack("<I", 0x4D4D4D4D):
|
if seccfg_data[:0xC] == b"AND_SECCFG_v":
|
||||||
# Probe antother seccfg format
|
sc_org = seccfgV3(hwc, self.mtk)
|
||||||
state, msg = self.seccfg_custom_V3(seccfg_data, lockflag, hwc, partition)
|
if not sc_org.parse(seccfg_data):
|
||||||
if state:
|
return False, "V3 Device has is either already unlocked or algo is unknown. Aborting."
|
||||||
return True, msg
|
writedata = sc_org.create(lockflag)
|
||||||
else:
|
else:
|
||||||
self.info(msg)
|
sc_org = seccfgV4(hwc,self.mtk)
|
||||||
|
if not sc_org.parse(seccfg_data):
|
||||||
return False, "Unknown seccfg partition header. Aborting unlock."
|
return False, "Error on parsing seccfg."
|
||||||
|
sc_new = seccfgV4(hwc,self.mtk)
|
||||||
if not sc_org.parse(seccfg_data):
|
self.setotp(hwc)
|
||||||
return False, "Error on parsing seccfg."
|
hwtype = "hw"
|
||||||
sc_new = seccfg(hwc)
|
V3 = True
|
||||||
self.setotp(hwc)
|
|
||||||
hwtype = "hw"
|
|
||||||
V3 = True
|
|
||||||
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
|
||||||
if sc_org.hash != sc_new.hash:
|
|
||||||
V3=False
|
|
||||||
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
||||||
if sc_org.hash != sc_new.hash:
|
|
||||||
hwtype = "sw"
|
|
||||||
sc_new.create(sc_org=sc_org, hwtype=hwtype)
|
|
||||||
if sc_org.hash != sc_new.hash:
|
if sc_org.hash != sc_new.hash:
|
||||||
return False, "Device has is either already unlocked or algo is unknown. Aborting."
|
V3=False
|
||||||
writedata = sc_new.create(sc_org=None, hwtype=hwtype, lockflag=lockflag, V3=V3)
|
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
||||||
|
if sc_org.hash != sc_new.hash:
|
||||||
|
hwtype = "sw"
|
||||||
|
sc_new.create(sc_org=sc_org, hwtype=hwtype)
|
||||||
|
if sc_org.hash != sc_new.hash:
|
||||||
|
return False, "Device has is either already unlocked or algo is unknown. Aborting."
|
||||||
|
writedata = sc_new.create(sc_org=None, hwtype=hwtype, lockflag=lockflag, V3=V3)
|
||||||
if self.legacy.writeflash(addr=partition.sector * self.mtk.daloader.daconfig.pagesize,
|
if self.legacy.writeflash(addr=partition.sector * self.mtk.daloader.daconfig.pagesize,
|
||||||
length=len(writedata),
|
length=len(writedata),
|
||||||
filename=None, wdata=writedata, parttype="user", display=True):
|
filename=None, wdata=writedata, parttype="user", display=True):
|
||||||
|
@ -380,7 +282,8 @@ class legacyext(metaclass=LogBase):
|
||||||
open(os.path.join("logs", "hrid.txt"), "wb").write(hexlify(hrid))
|
open(os.path.join("logs", "hrid.txt"), "wb").write(hexlify(hrid))
|
||||||
"""
|
"""
|
||||||
if hwcode == 0x699 and self.config.chipconfig.sej_base:
|
if hwcode == 0x699 and self.config.chipconfig.sej_base:
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
|
otp = self.config.get_otp()
|
||||||
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
||||||
if mtee3:
|
if mtee3:
|
||||||
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
|
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
|
||||||
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
||||||
|
@ -397,21 +300,22 @@ class legacyext(metaclass=LogBase):
|
||||||
meid_addr = self.config.chipconfig.meid_addr
|
meid_addr = self.config.chipconfig.meid_addr
|
||||||
meid = b"".join([pack("<I", val) for val in self.readmem(meid_addr, 4)])
|
meid = b"".join([pack("<I", val) for val in self.readmem(meid_addr, 4)])
|
||||||
if meid != b"":
|
if meid != b"":
|
||||||
|
otp = self.config.get_otp()
|
||||||
self.info("Generating sej rpmbkey...")
|
self.info("Generating sej rpmbkey...")
|
||||||
self.setotp(hwc)
|
self.setotp(hwc)
|
||||||
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej")
|
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
||||||
if rpmbkey:
|
if rpmbkey:
|
||||||
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
|
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
|
||||||
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
self.info("Generating sej mtee...")
|
self.info("Generating sej mtee...")
|
||||||
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej")
|
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
||||||
if mtee:
|
if mtee:
|
||||||
self.info("MTEE : " + hexlify(mtee).decode('utf-8'))
|
self.info("MTEE : " + hexlify(mtee).decode('utf-8'))
|
||||||
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
|
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
|
||||||
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
||||||
self.info("Generating sej mtee3...")
|
self.info("Generating sej mtee3...")
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
||||||
if mtee3:
|
if mtee3:
|
||||||
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
|
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
|
||||||
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
||||||
|
|
|
@ -244,6 +244,12 @@ class DAloader(metaclass=LogBase):
|
||||||
else:
|
else:
|
||||||
return self.lft.generate_keys()
|
return self.lft.generate_keys()
|
||||||
|
|
||||||
|
def readfuses(self):
|
||||||
|
if self.xflash:
|
||||||
|
return self.xft.readfuses()
|
||||||
|
else:
|
||||||
|
return self.lft.readfuses()
|
||||||
|
|
||||||
def is_patched(self):
|
def is_patched(self):
|
||||||
return self.da.patch
|
return self.da.patch
|
||||||
|
|
||||||
|
|
|
@ -288,13 +288,13 @@ class PLTools(metaclass=LogBase):
|
||||||
self.error("Error on dumping Bootrom.")
|
self.error("Error on dumping Bootrom.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def run_crypto(self, data, iv, btype="sej", encrypt=True):
|
def run_crypto(self, data, iv, btype="sej", encrypt=True, otp=None):
|
||||||
if data is None:
|
if data is None:
|
||||||
data = bytearray()
|
data = bytearray()
|
||||||
for i in range(32):
|
for i in range(32):
|
||||||
data.append(self.config.meid[i % len(self.config.meid)])
|
data.append(self.config.meid[i % len(self.config.meid)])
|
||||||
if btype == "":
|
if btype == "":
|
||||||
encrypted = self.hwcrypto.aes_hwcrypt(data=data, iv=iv, encrypt=encrypt, btype=btype)
|
encrypted = self.hwcrypto.aes_hwcrypt(data=data, iv=iv, encrypt=encrypt, btype=btype, otp=otp)
|
||||||
return encrypted
|
return encrypted
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
from struct import unpack, pack
|
from struct import unpack, pack
|
||||||
|
from mtkclient.Library.utils import structhelper_io
|
||||||
|
from io import BytesIO
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
from mtkclient.config.mtk_config import Mtk_Config
|
||||||
|
|
||||||
class seccfg:
|
|
||||||
def __init__(self, hwc):
|
class seccfgV4:
|
||||||
|
def __init__(self, hwc, mtk):
|
||||||
self.hwc = hwc
|
self.hwc = hwc
|
||||||
|
self.mtk = mtk
|
||||||
self.magic = 0x4D4D4D4D
|
self.magic = 0x4D4D4D4D
|
||||||
self.seccfg_ver = None
|
self.seccfg_ver = None
|
||||||
self.seccfg_size = None
|
self.seccfg_size = None
|
||||||
|
@ -15,12 +20,18 @@ class seccfg:
|
||||||
self.hash = b""
|
self.hash = b""
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
seccfg_data = unpack("<IIIIIII", data[:7 * 4])
|
rf = structhelper_io(BytesIO(bytearray(data)))
|
||||||
self.magic, self.seccfg_ver, self.seccfg_size, self.lock_state, self.critical_lock_state, \
|
self.magic = rf.dword()
|
||||||
self.sboot_runtime, self.endflag = seccfg_data
|
self.seccfg_ver = rf.dword()
|
||||||
self.hash = data[7 * 4:(7 * 4) + 32]
|
self.seccfg_size = rf.dword()
|
||||||
|
self.lock_state = rf.dword()
|
||||||
|
self.critical_lock_state = rf.dword()
|
||||||
|
self.sboot_runtime = rf.dword()
|
||||||
|
self.endflag = rf.dword()
|
||||||
|
rf.seek(self.seccfg_size - 0x20)
|
||||||
|
self.hash = rf.bytes(0x20)
|
||||||
if self.magic != 0x4D4D4D4D or self.endflag != 0x45454545:
|
if self.magic != 0x4D4D4D4D or self.endflag != 0x45454545:
|
||||||
self.error("Unknown seccfg structure !")
|
self.error("Unknown V4 seccfg structure !")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -69,5 +80,191 @@ class seccfg:
|
||||||
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, True)
|
||||||
self.hash = enc_hash
|
self.hash = enc_hash
|
||||||
data = seccfg_data + enc_hash
|
data = seccfg_data + enc_hash
|
||||||
data += b"\x00" * (0x200 - len(data))
|
while len(data) % 0x200 != 0:
|
||||||
|
data += b"\x00"
|
||||||
return bytearray(data)
|
return bytearray(data)
|
||||||
|
|
||||||
|
|
||||||
|
class SECCFG_STATUS:
|
||||||
|
SEC_CFG_COMPLETE_NUM = 0x43434343 # CCCC
|
||||||
|
SEC_CFG_INCOMPLETE_NUM = 0x49494949 # IIII
|
||||||
|
|
||||||
|
|
||||||
|
class SECCFG_ATTR:
|
||||||
|
ATTR_LOCK = 0x6000
|
||||||
|
ATTR_VERIFIED = 0x6001
|
||||||
|
ATTR_CUSTOM = 0x6002
|
||||||
|
ATTR_MP_DEFAULT = 0x6003
|
||||||
|
ATTR_DEFAULT = 0x33333333
|
||||||
|
ATTR_UNLOCK = 0x44444444
|
||||||
|
|
||||||
|
|
||||||
|
class SIU_STATUS:
|
||||||
|
UBOOT_UPDATED_BY_SIU = 0x0001
|
||||||
|
BOOT_UPDATED_BY_SIU = 0x0010
|
||||||
|
RECOVERY_UPDATED_BY_SIU = 0x0100
|
||||||
|
SYSTEM_UPDATED_BY_SIU = 0x1000
|
||||||
|
|
||||||
|
|
||||||
|
class ROM_TYPE:
|
||||||
|
NORMAL_ROM = 0x01
|
||||||
|
YAFFS_IMG = 0x08
|
||||||
|
|
||||||
|
|
||||||
|
class SEC_IMG_ATTR:
|
||||||
|
ATTR_SEC_IMG_UPDATE = 0x10,
|
||||||
|
ATTR_SEC_IMG_COMPLETE = 0x43434343, # CCCC
|
||||||
|
ATTR_SEC_IMG_INCOMPLETE = 0x49494949, # IIII
|
||||||
|
ATTR_SEC_IMG_FORCE_UPDATE = 0x46464646 # FFFF
|
||||||
|
|
||||||
|
|
||||||
|
class seccfgV3:
|
||||||
|
def __init__(self, hwc, mtk):
|
||||||
|
self.hwtype = None
|
||||||
|
self.data = None
|
||||||
|
self.org_data = None
|
||||||
|
self.hwc = hwc
|
||||||
|
self.mtk = mtk
|
||||||
|
self.info = b"AND_SECCFG_v\x00\x00\x00\x00"
|
||||||
|
self.magic = 0x4D4D4D4D
|
||||||
|
self.seccfg_ver = 3
|
||||||
|
self.seccfg_size = 0x1860
|
||||||
|
self.seccfg_enc_len = 0x01000000 # 0x07F20000 for unlocked
|
||||||
|
self.seccfg_enc_offset = 0
|
||||||
|
self.endflag = 0x45454545
|
||||||
|
self.sw_sec_lock_try = 0
|
||||||
|
self.sw_sec_lock_done = 0
|
||||||
|
self.page_size = 0
|
||||||
|
self.page_count = 0
|
||||||
|
self.imginfo = b"\x00" * (0x68 * 20)
|
||||||
|
self.siu_status = 0
|
||||||
|
self.seccfg_status = SECCFG_STATUS.SEC_CFG_COMPLETE_NUM
|
||||||
|
self.seccfg_attr = SECCFG_ATTR.ATTR_DEFAULT
|
||||||
|
self.seccfg_ext = b"\x00" * 0x1004
|
||||||
|
if self.hwc.read32 is not None:
|
||||||
|
self.setotp(hwc)
|
||||||
|
|
||||||
|
def setotp(self, hwc):
|
||||||
|
otp = None
|
||||||
|
if self.mtk.config.preloader is not None:
|
||||||
|
idx = self.mtk.config.preloader.find(b"\x4D\x4D\x4D\x01\x30")
|
||||||
|
if idx != -1:
|
||||||
|
otp = self.mtk.config.preloader[idx + 0xC:idx + 0xC + 32]
|
||||||
|
if otp is None:
|
||||||
|
otp = 32 * b"\x00"
|
||||||
|
hwc.sej.sej_set_otp(otp)
|
||||||
|
|
||||||
|
def parse(self, data):
|
||||||
|
if data[:0x10] != b"AND_SECCFG_v\x00\x00\x00\x00":
|
||||||
|
return False
|
||||||
|
rf = structhelper_io(BytesIO(bytearray(data)))
|
||||||
|
self.info = rf.bytes(0x10)
|
||||||
|
self.magic = rf.dword()
|
||||||
|
self.seccfg_ver = rf.dword()
|
||||||
|
self.seccfg_size = rf.dword()
|
||||||
|
self.seccfg_enc_offset = rf.dword()
|
||||||
|
self.seccfg_enc_len = rf.dword() # 0x1 = Locked, 0xF207 = Unlocked
|
||||||
|
self.sw_sec_lock_try = rf.bytes(1)
|
||||||
|
self.sw_sec_lock_done = rf.bytes(1)
|
||||||
|
self.page_size = rf.short()
|
||||||
|
self.page_count = rf.dword()
|
||||||
|
self.data = rf.bytes(self.seccfg_size - 0x2C - 4)
|
||||||
|
self.endflag = rf.dword()
|
||||||
|
if self.magic != 0x4D4D4D4D or self.endflag != 0x45454545:
|
||||||
|
self.error("Unknown V3 seccfg structure !")
|
||||||
|
return False
|
||||||
|
ret = self.hwc.sej.sej_sec_cfg_sw(self.data, False)
|
||||||
|
if ret[:4] != b"IIII":
|
||||||
|
ret = self.hwc.sej.sej_sec_cfg_hw(self.data, False)
|
||||||
|
if ret[:4] != b"IIII":
|
||||||
|
ret = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, False)
|
||||||
|
if ret[:4] != b"IIII":
|
||||||
|
self.error("Unknown V3 seccfg encryption !")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
self.hwtype = "V3"
|
||||||
|
else:
|
||||||
|
self.hwtype = "V2"
|
||||||
|
else:
|
||||||
|
self.hwtype = "SW"
|
||||||
|
self.org_data = ret
|
||||||
|
ed = structhelper_io(BytesIO(bytearray(ret)))
|
||||||
|
self.imginfo = [ed.bytes(0x68) for _ in range(20)]
|
||||||
|
self.siu_status = ed.dword()
|
||||||
|
self.seccfg_status = ed.dword()
|
||||||
|
if self.seccfg_status not in [SECCFG_STATUS.SEC_CFG_COMPLETE_NUM,SECCFG_STATUS.SEC_CFG_INCOMPLETE_NUM]:
|
||||||
|
return False
|
||||||
|
self.seccfg_attr = ed.dword()
|
||||||
|
if self.seccfg_attr not in [SECCFG_ATTR.ATTR_DEFAULT,SECCFG_ATTR.ATTR_UNLOCK,SECCFG_ATTR.ATTR_MP_DEFAULT,
|
||||||
|
SECCFG_ATTR.ATTR_LOCK, SECCFG_ATTR.ATTR_CUSTOM,SECCFG_ATTR.ATTR_VERIFIED]:
|
||||||
|
return False
|
||||||
|
self.seccfg_ext = ed.bytes(0x1000 + 4)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def create(self, lockflag: str = "unlock"):
|
||||||
|
seccfg_attr_new = SECCFG_ATTR.ATTR_DEFAULT
|
||||||
|
if lockflag == "unlock":
|
||||||
|
self.seccfg_enc_len = 0x07F20000
|
||||||
|
seccfg_attr_new = SECCFG_ATTR.ATTR_UNLOCK
|
||||||
|
elif lockflag == "lock":
|
||||||
|
self.seccfg_enc_len = 0x01000000
|
||||||
|
seccfg_attr_new = SECCFG_ATTR.ATTR_DEFAULT
|
||||||
|
|
||||||
|
"""
|
||||||
|
if lockflag == "lock" and self.seccfg_attr != SECCFG_ATTR.ATTR_UNLOCK:
|
||||||
|
return False, ("Can't find lock state, current (%#x)" % self.seccfg_attr)
|
||||||
|
elif lockflag == "unlock" and self.seccfg_attr != SECCFG_ATTR.ATTR_DEFAULT \
|
||||||
|
and self.seccfg_attr != SECCFG_ATTR.ATTR_MP_DEFAULT \
|
||||||
|
and self.seccfg_attr != SECCFG_ATTR.ATTR_CUSTOM \
|
||||||
|
and self.seccfg_attr != SECCFG_ATTR.ATTR_VERIFIED \
|
||||||
|
and self.seccfg_attr != SECCFG_ATTR.ATTR_LOCK:
|
||||||
|
return False, ("Can't find unlock state, current (%#x)" % self.seccfg_attr)
|
||||||
|
"""
|
||||||
|
data = bytearray()
|
||||||
|
wf = BytesIO(data)
|
||||||
|
wf.write(self.info)
|
||||||
|
wf.write(int.to_bytes(self.magic, 4, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.seccfg_ver, 4, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.seccfg_size, 4, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.seccfg_enc_offset, 4, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.seccfg_enc_len, 4, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.sw_sec_lock_try, 1, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.sw_sec_lock_done, 1, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.page_size, 2, 'little'))
|
||||||
|
wf.write(int.to_bytes(self.page_count, 4, 'little'))
|
||||||
|
|
||||||
|
ed = BytesIO()
|
||||||
|
for imginfo in self.imginfo:
|
||||||
|
ed.write(imginfo)
|
||||||
|
ed.write(int.to_bytes(self.siu_status, 4, 'little'))
|
||||||
|
ed.write(int.to_bytes(self.seccfg_status, 4, 'little'))
|
||||||
|
ed.write(int.to_bytes(seccfg_attr_new, 4, 'little'))
|
||||||
|
ed.write(self.seccfg_ext)
|
||||||
|
data = ed.getbuffer()
|
||||||
|
if self.hwtype == "SW":
|
||||||
|
data = self.hwc.sej.sej_sec_cfg_sw(data, True)
|
||||||
|
elif self.hwtype == "V2":
|
||||||
|
data = self.hwc.sej.sej_sec_cfg_hw(data, True)
|
||||||
|
elif self.hwtype == "V3":
|
||||||
|
data = self.hwc.sej.sej_sec_cfg_hw_V3(data, True)
|
||||||
|
wf.write(data)
|
||||||
|
wf.write(int.to_bytes(self.endflag, 4, 'little'))
|
||||||
|
|
||||||
|
data = bytearray(wf.getbuffer())
|
||||||
|
while len(data) % 0x200 != 0:
|
||||||
|
data += b"\x00"
|
||||||
|
return bytearray(data)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
with open("seccfg.bin","rb") as rf:
|
||||||
|
data = rf.read()
|
||||||
|
from hwcrypto import hwcrypto, crypto_setup
|
||||||
|
setup = crypto_setup()
|
||||||
|
hwc = hwcrypto(setup)
|
||||||
|
class mtk:
|
||||||
|
config = Mtk_Config()
|
||||||
|
sej_base = None
|
||||||
|
v3=seccfgV3(hwc,mtk)
|
||||||
|
v3.parse(data)
|
||||||
|
newdata=v3.create("lock")
|
||||||
|
print(newdata.hex())
|
|
@ -29,8 +29,6 @@ except ImportError:
|
||||||
from struct import unpack, pack
|
from struct import unpack, pack
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from io import BytesIO
|
|
||||||
|
|
||||||
class mtktee:
|
class mtktee:
|
||||||
magic = None
|
magic = None
|
||||||
hdrlen = None
|
hdrlen = None
|
||||||
|
@ -805,7 +803,7 @@ def write_object(definition, *args):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def print_progress(iteration, total, prefix='', suffix='', decimals=1, bar_length=100):
|
def print_progress(iteration, total, prefix='', suffix='', decimals=1, bar_length=50):
|
||||||
"""
|
"""
|
||||||
Call in a loop to create terminal progress bar
|
Call in a loop to create terminal progress bar
|
||||||
@params:
|
@params:
|
||||||
|
|
|
@ -6,7 +6,7 @@ from mtkclient.config.brom_config import efuse
|
||||||
from mtkclient.Library.error import ErrorHandler, ErrorCodes_XFlash
|
from mtkclient.Library.error import ErrorHandler, ErrorCodes_XFlash
|
||||||
from mtkclient.Library.hwcrypto import crypto_setup, hwcrypto
|
from mtkclient.Library.hwcrypto import crypto_setup, hwcrypto
|
||||||
from mtkclient.Library.utils import LogBase, progress, logsetup, find_binary
|
from mtkclient.Library.utils import LogBase, progress, logsetup, find_binary
|
||||||
from mtkclient.Library.seccfg import seccfg
|
from mtkclient.Library.seccfg import seccfgV3, seccfgV4
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
from mtkclient.Library.utils import mtktee
|
from mtkclient.Library.utils import mtktee
|
||||||
import json
|
import json
|
||||||
|
@ -372,11 +372,11 @@ class xflashext(metaclass=LogBase):
|
||||||
hwc = self.cryptosetup()
|
hwc = self.cryptosetup()
|
||||||
if self.config.chipconfig.meid_addr:
|
if self.config.chipconfig.meid_addr:
|
||||||
meid = self.config.get_meid()
|
meid = self.config.get_meid()
|
||||||
|
otp = self.config.get_otp()
|
||||||
if meid != b"\x00" * 16:
|
if meid != b"\x00" * 16:
|
||||||
# self.config.set_meid(meid)
|
# self.config.set_meid(meid)
|
||||||
self.info("Generating sej rpmbkey...")
|
self.info("Generating sej rpmbkey...")
|
||||||
self.setotp(hwc)
|
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
||||||
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej")
|
|
||||||
if rpmbkey is not None:
|
if rpmbkey is not None:
|
||||||
if self.cmd(XCmd.CUSTOM_SET_RPMB_KEY):
|
if self.cmd(XCmd.CUSTOM_SET_RPMB_KEY):
|
||||||
self.xsend(rpmbkey)
|
self.xsend(rpmbkey)
|
||||||
|
@ -503,8 +503,6 @@ class xflashext(metaclass=LogBase):
|
||||||
def seccfg(self, lockflag):
|
def seccfg(self, lockflag):
|
||||||
if lockflag not in ["unlock", "lock"]:
|
if lockflag not in ["unlock", "lock"]:
|
||||||
return False, "Valid flags are: unlock, lock"
|
return False, "Valid flags are: unlock, lock"
|
||||||
hwc = self.cryptosetup()
|
|
||||||
sc_org = seccfg(hwc)
|
|
||||||
data, guid_gpt = self.xflash.partition.get_gpt(self.mtk.config.gpt_settings, "user")
|
data, guid_gpt = self.xflash.partition.get_gpt(self.mtk.config.gpt_settings, "user")
|
||||||
seccfg_data = None
|
seccfg_data = None
|
||||||
partition = None
|
partition = None
|
||||||
|
@ -522,23 +520,29 @@ class xflashext(metaclass=LogBase):
|
||||||
return False, "Couldn't detect existing seccfg partition. Aborting unlock."
|
return False, "Couldn't detect existing seccfg partition. Aborting unlock."
|
||||||
if seccfg_data[:4] != pack("<I", 0x4D4D4D4D):
|
if seccfg_data[:4] != pack("<I", 0x4D4D4D4D):
|
||||||
return False, "Unknown seccfg partition header. Aborting unlock."
|
return False, "Unknown seccfg partition header. Aborting unlock."
|
||||||
|
hwc = self.cryptosetup()
|
||||||
if not sc_org.parse(seccfg_data):
|
if seccfg_data[:0xC] == b"AND_SECCFG_v":
|
||||||
return False, "Error on parsing seccfg"
|
sc_org = seccfgV3(hwc, self.mtk)
|
||||||
sc_new = seccfg(hwc)
|
if not sc_org.parse(seccfg_data):
|
||||||
self.setotp(hwc)
|
return False, "V3 Device has is either already unlocked or algo is unknown. Aborting."
|
||||||
hwtype = "hw"
|
writedata = sc_org.create(lockflag)
|
||||||
V3 = True
|
else:
|
||||||
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
sc_org = seccfgV4(hwc, self.mtk)
|
||||||
if sc_org.hash != sc_new.hash:
|
if not sc_org.parse(seccfg_data):
|
||||||
V3 = False
|
return False, "Error on parsing seccfg"
|
||||||
|
sc_new = seccfgV4(hwc, self.mtk)
|
||||||
|
hwtype = "hw"
|
||||||
|
V3 = True
|
||||||
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
||||||
if sc_org.hash != sc_new.hash:
|
|
||||||
hwtype = "sw"
|
|
||||||
sc_new.create(sc_org=sc_org, hwtype=hwtype)
|
|
||||||
if sc_org.hash != sc_new.hash:
|
if sc_org.hash != sc_new.hash:
|
||||||
return False, "Device has is either already unlocked or algo is unknown. Aborting."
|
V3 = False
|
||||||
writedata = sc_new.create(sc_org=None, hwtype=hwtype, lockflag=lockflag, V3=V3)
|
sc_new.create(sc_org=sc_org, hwtype=hwtype, V3=V3)
|
||||||
|
if sc_org.hash != sc_new.hash:
|
||||||
|
hwtype = "sw"
|
||||||
|
sc_new.create(sc_org=sc_org, hwtype=hwtype)
|
||||||
|
if sc_org.hash != sc_new.hash:
|
||||||
|
return False, "Device has is either already unlocked or algo is unknown. Aborting."
|
||||||
|
writedata = sc_new.create(sc_org=None, hwtype=hwtype, lockflag=lockflag, V3=V3)
|
||||||
if self.xflash.writeflash(addr=partition.sector * self.mtk.daloader.daconfig.pagesize,
|
if self.xflash.writeflash(addr=partition.sector * self.mtk.daloader.daconfig.pagesize,
|
||||||
length=len(writedata),
|
length=len(writedata),
|
||||||
filename=None, wdata=writedata, parttype="user", display=True):
|
filename=None, wdata=writedata, parttype="user", display=True):
|
||||||
|
@ -569,13 +573,27 @@ class xflashext(metaclass=LogBase):
|
||||||
return data
|
return data
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def read_fuses(self):
|
||||||
|
if self.mtk.config.chipconfig.efuse_addr is not None:
|
||||||
|
base = self.mtk.config.chipconfig.efuse_addr
|
||||||
|
hwcode = self.mtk.config.hwcode
|
||||||
|
efuseconfig = efuse(base, hwcode)
|
||||||
|
data = []
|
||||||
|
for idx in range(len(efuseconfig.efuses)):
|
||||||
|
addr = efuseconfig.efuses[idx]
|
||||||
|
data.append(bytearray(self.mtk.daloader.peek(addr=addr, length=4)))
|
||||||
|
return data
|
||||||
|
|
||||||
def generate_keys(self):
|
def generate_keys(self):
|
||||||
hwc = self.cryptosetup()
|
hwc = self.cryptosetup()
|
||||||
meid = self.config.get_meid()
|
meid = self.config.get_meid()
|
||||||
socid = self.config.get_socid()
|
socid = self.config.get_socid()
|
||||||
hwcode = self.config.get_hwcode()
|
hwcode = self.config.get_hwcode()
|
||||||
cid = self.config.get_cid()
|
cid = self.config.get_cid()
|
||||||
|
otp = self.config.get_otp()
|
||||||
retval = {}
|
retval = {}
|
||||||
|
#data=hwc.aes_hwcrypt(data=bytes.fromhex("F6 25 25 AD 0C A4 3A AA CC EF 93 1F 2D C2 A3 EE"), mode="sst", btype="sej",
|
||||||
|
# encrypt=True)
|
||||||
if meid is not None:
|
if meid is not None:
|
||||||
self.info("MEID : " + hexlify(meid).decode('utf-8'))
|
self.info("MEID : " + hexlify(meid).decode('utf-8'))
|
||||||
retval["meid"] = hexlify(meid).decode('utf-8')
|
retval["meid"] = hexlify(meid).decode('utf-8')
|
||||||
|
@ -668,18 +686,18 @@ class xflashext(metaclass=LogBase):
|
||||||
# self.config.set_meid(meid)
|
# self.config.set_meid(meid)
|
||||||
self.info("Generating sej rpmbkey...")
|
self.info("Generating sej rpmbkey...")
|
||||||
self.setotp(hwc)
|
self.setotp(hwc)
|
||||||
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej")
|
rpmbkey = hwc.aes_hwcrypt(mode="rpmb", data=meid, btype="sej", otp=otp)
|
||||||
if rpmbkey:
|
if rpmbkey:
|
||||||
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
|
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
|
||||||
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
self.info("Generating sej mtee...")
|
self.info("Generating sej mtee...")
|
||||||
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej")
|
mtee = hwc.aes_hwcrypt(mode="mtee", btype="sej", otp=otp)
|
||||||
if mtee:
|
if mtee:
|
||||||
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
|
self.config.hwparam.writesetting("mtee", hexlify(mtee).decode('utf-8'))
|
||||||
self.info("MTEE : " + hexlify(mtee).decode('utf-8'))
|
self.info("MTEE : " + hexlify(mtee).decode('utf-8'))
|
||||||
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
retval["mtee"] = hexlify(mtee).decode('utf-8')
|
||||||
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej")
|
mtee3 = hwc.aes_hwcrypt(mode="mtee3", btype="sej", otp=otp)
|
||||||
if mtee3:
|
if mtee3:
|
||||||
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
|
||||||
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
|
self.info("MTEE3 : " + hexlify(mtee3).decode('utf-8'))
|
||||||
|
|
|
@ -66,6 +66,7 @@ class Mtk_Config(metaclass=LogBase):
|
||||||
self.hwparam_path = "logs"
|
self.hwparam_path = "logs"
|
||||||
self.sram = None
|
self.sram = None
|
||||||
self.dram = None
|
self.dram = None
|
||||||
|
self.otp = None
|
||||||
if loglevel == logging.DEBUG:
|
if loglevel == logging.DEBUG:
|
||||||
logfilename = os.path.join("logs", "log.txt")
|
logfilename = os.path.join("logs", "log.txt")
|
||||||
fh = logging.FileHandler(logfilename)
|
fh = logging.FileHandler(logfilename)
|
||||||
|
@ -108,6 +109,22 @@ class Mtk_Config(metaclass=LogBase):
|
||||||
self.meid = meid
|
self.meid = meid
|
||||||
self.hwparam.writesetting("meid", hexlify(meid).decode('utf-8'))
|
self.hwparam.writesetting("meid", hexlify(meid).decode('utf-8'))
|
||||||
|
|
||||||
|
def get_otp(self):
|
||||||
|
if self.otp is None:
|
||||||
|
self.otp = self.hwparam.loadsetting("otp")
|
||||||
|
if self.preloader is not None:
|
||||||
|
idx = self.preloader.find(b"\x4D\x4D\x4D\x01\x30")
|
||||||
|
if idx != -1:
|
||||||
|
self.otp = self.preloader[idx + 0xC:idx + 0xC + 32]
|
||||||
|
self.hwparam.writesetting("otp",hexlify(self.otp).decode('utf-8'))
|
||||||
|
if self.otp is None:
|
||||||
|
self.otp = 32 * b"\x00"
|
||||||
|
return self.otp
|
||||||
|
|
||||||
|
def set_otp(self,otp):
|
||||||
|
self.otp = otp
|
||||||
|
self.hwparam.writesetting("otp",hexlify(otp).decode('utf-8'))
|
||||||
|
|
||||||
def get_meid(self):
|
def get_meid(self):
|
||||||
if self.meid is None:
|
if self.meid is None:
|
||||||
if self.peek is not None:
|
if self.peek is not None:
|
||||||
|
|
8
stage2
8
stage2
|
@ -444,25 +444,25 @@ class Stage2(metaclass=LogBase):
|
||||||
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
|
||||||
return retval, keyinfo
|
return retval, keyinfo
|
||||||
if mode == "sej_aes_decrypt":
|
if mode == "sej_aes_decrypt":
|
||||||
dec_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=False)
|
dec_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=False, otp=otp)
|
||||||
keyinfo+="\n"
|
keyinfo+="\n"
|
||||||
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
|
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
|
||||||
keyinfo+="\n"
|
keyinfo+="\n"
|
||||||
return dec_data, keyinfo
|
return dec_data, keyinfo
|
||||||
elif mode == "sej_aes_encrypt":
|
elif mode == "sej_aes_encrypt":
|
||||||
enc_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=True)
|
enc_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=True, otp=otp)
|
||||||
keyinfo+="\n"
|
keyinfo+="\n"
|
||||||
keyinfo+="Data: " + hexlify(enc_data).decode('utf-8')
|
keyinfo+="Data: " + hexlify(enc_data).decode('utf-8')
|
||||||
keyinfo+="\n"
|
keyinfo+="\n"
|
||||||
return enc_data, keyinfo
|
return enc_data, keyinfo
|
||||||
elif mode == "sej_sst_decrypt":
|
elif mode == "sej_sst_decrypt":
|
||||||
dec_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=False)
|
dec_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=False, otp=otp)
|
||||||
keyinfo+="\n"
|
keyinfo+="\n"
|
||||||
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
|
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
|
||||||
keyinfo+="\n"
|
keyinfo+="\n"
|
||||||
return dec_data, keyinfo
|
return dec_data, keyinfo
|
||||||
elif mode == "sej_sst_encrypt":
|
elif mode == "sej_sst_encrypt":
|
||||||
enc_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=True)
|
enc_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=True, otp=otp)
|
||||||
keyinfo += "\n"
|
keyinfo += "\n"
|
||||||
keyinfo += "Data: " + hexlify(enc_data).decode('utf-8')
|
keyinfo += "Data: " + hexlify(enc_data).decode('utf-8')
|
||||||
keyinfo += "\n"
|
keyinfo += "\n"
|
||||||
|
|
Loading…
Reference in a new issue