-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMtkCrypto.cs
More file actions
150 lines (130 loc) · 4.89 KB
/
Copy pathMtkCrypto.cs
File metadata and controls
150 lines (130 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using MtkClient.Library.Config;
using MtkClient.Library.Utils;
namespace MtkClient.Library
{
public class MtkCrypto : LogBase
{
private readonly MtkConfig _config;
// Known keys for various MediaTek operations
private static readonly byte[] SejKey = new byte[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
private static readonly byte[] DefaultOtpKey = new byte[]
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
public MtkCrypto(MtkConfig config, LogLevel logLevel = LogLevel.Info)
{
InitLogger(logLevel);
_config = config;
}
public byte[] GenerateHwKey(byte[] meid, byte[] socId = null, byte[] otp = null)
{
try
{
if (meid == null || meid.Length == 0)
{
Warning("No MEID available for key generation");
return null;
}
// Combine available data
var keyMaterial = new byte[meid.Length + (socId?.Length ?? 0) + (otp?.Length ?? 0)];
int offset = 0;
Array.Copy(meid, 0, keyMaterial, offset, meid.Length);
offset += meid.Length;
if (socId != null)
{
Array.Copy(socId, 0, keyMaterial, offset, socId.Length);
offset += socId.Length;
}
if (otp != null)
Array.Copy(otp, 0, keyMaterial, offset, otp.Length);
var hash = CryptUtils.Hash.Sha256(keyMaterial);
var key = new byte[16];
Array.Copy(hash, key, 16);
Info($"Generated HW key: {MtkUtils.ToHex(key)}");
return key;
}
catch (Exception ex)
{
Error($"Key generation failed: {ex.Message}");
return null;
}
}
public byte[] DecryptSla(byte[] data, byte[] key)
{
try
{
if (key == null || key.Length < 16) return null;
var iv = new byte[16];
return CryptUtils.Aes.AesCbcDecrypt(key, iv, data);
}
catch (Exception ex)
{
Error($"SLA decrypt failed: {ex.Message}");
return null;
}
}
public byte[] DecryptMtkTee(byte[] data, byte[] key = null)
{
try
{
var tee = new MTKTee();
tee.Parse(data);
if (tee.Magic != 0x5F5F544545545F5F) // __TEET__
{
Warning("Not a valid MTK TEE file");
return null;
}
if (key == null)
key = GenerateHwKey(_config.Meid, _config.SocId, _config.GetOtp());
if (key == null) return null;
var derivedKey = CryptUtils.Hash.Sha256(tee.KeySeed.Concat(key).ToArray());
var aesKey = new byte[16];
Array.Copy(derivedKey, aesKey, 16);
var iv = new byte[16];
Array.Copy(tee.IvSeed, iv, 16);
var decrypted = CryptUtils.Aes.AesCbcDecrypt(aesKey, iv, tee.Data);
Info($"Decrypted MTK TEE: {decrypted.Length} bytes");
return decrypted;
}
catch (Exception ex)
{
Error($"MTK TEE decrypt failed: {ex.Message}");
return null;
}
}
public bool GenerateAndSaveKeys(string outputDir)
{
try
{
if (!Directory.Exists(outputDir))
Directory.CreateDirectory(outputDir);
if (_config.Meid != null)
File.WriteAllText(Path.Combine(outputDir, "meid.txt"), MtkUtils.ToHex(_config.Meid));
if (_config.SocId != null)
File.WriteAllText(Path.Combine(outputDir, "socid.txt"), MtkUtils.ToHex(_config.SocId));
var otp = _config.GetOtp();
if (otp != null)
File.WriteAllText(Path.Combine(outputDir, "otp.txt"), MtkUtils.ToHex(otp));
var hwKey = GenerateHwKey(_config.Meid, _config.SocId, otp);
if (hwKey != null)
File.WriteAllText(Path.Combine(outputDir, "hwkey.txt"), MtkUtils.ToHex(hwKey));
Info($"Keys saved to {outputDir}");
return true;
}
catch (Exception ex)
{
Error($"Save keys failed: {ex.Message}");
return false;
}
}
}
}