Skip to content

Commit b7ba0b9

Browse files
bwssytemsa1aw
authored andcommitted
Update all devices for correct decryption and also streamlined
descryption.
1 parent 491971f commit b7ba0b9

File tree

6 files changed

+66
-102
lines changed

6 files changed

+66
-102
lines changed

src/main/java/com/github/mob41/blapi/A1Device.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import com.github.mob41.blapi.mac.Mac;
4040
import com.github.mob41.blapi.pkt.CmdPayload;
4141
import com.github.mob41.blapi.pkt.Payload;
42-
import com.github.mob41.blapi.pkt.auth.AES;
4342

4443
public class A1Device extends BLDevice {
4544

@@ -79,8 +78,7 @@ public byte[] getData() {
7978
int err = data[0x22] | (data[0x23] << 8);
8079

8180
if (err == 0) {
82-
AES aes = new AES(getIv(), getKey());
83-
byte[] pl = aes.decrypt(chgLen(subbytes(data, 56, 1024), 1024));
81+
byte[] pl = decryptFromDeviceMessage(data);
8482
log.debug("checkSensors Packet received bytes (decrypted): {}", DatatypeConverter.printHexBinary(pl));
8583

8684
float temp = (float) ((pl[0x4] * 10 + pl[0x5]) / 10.0);

src/main/java/com/github/mob41/blapi/BLDevice.java

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ public abstract class BLDevice implements Closeable {
7676
public static final byte[] INITIAL_IV = { 0x56, 0x2e, 0x17, (byte) 0x99, 0x6d, 0x09, 0x3d, 0x28, (byte) 0xdd,
7777
(byte) 0xb3, (byte) 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 }; // 16-short
7878

79+
public static final int DEFAULT_BYTES_SIZE = 0x38; // 56-bytes
80+
7981
// Devices type HEX
8082

8183
public static final short DEV_SP1 = 0x0;
@@ -255,7 +257,12 @@ public abstract class BLDevice implements Closeable {
255257
* implementation to handle MAC addresses
256258
*/
257259
private Mac mac;
258-
260+
261+
/**
262+
* Global AES decrytpor
263+
*/
264+
private static AES aes = null;
265+
259266
/**
260267
* Constructs a <code>BLDevice</code>, with a device type (constants),
261268
* hostname and MAC address
@@ -276,9 +283,7 @@ protected BLDevice(short deviceType, String deviceDesc, String host, Mac mac) th
276283
iv = INITIAL_IV;
277284
id = new byte[] { 0, 0, 0, 0 };
278285

279-
pktCount = 50000;
280-
// pktCount = new Random().nextInt(0xffff);
281-
// pktCount = 0;
286+
pktCount = new Random().nextInt(0xffff);
282287

283288
this.deviceType = deviceType;
284289
this.deviceDesc = deviceDesc;
@@ -289,6 +294,7 @@ protected BLDevice(short deviceType, String deviceDesc, String host, Mac mac) th
289294
sock = new DatagramSocket();
290295
sock.setReuseAddress(true);
291296
sock.setBroadcast(true);
297+
aes = new AES(iv, key);
292298
}
293299

294300
/**
@@ -326,25 +332,11 @@ public Mac getMac() {
326332
return mac;
327333
}
328334

329-
/**
330-
* Returns the encryption IV of this client
331-
*
332-
* @return a byte array containing the IV
333-
*/
334-
public byte[] getIv() {
335-
return iv;
336-
}
337-
338-
/**
339-
* Returns the encryption key of this client
340-
*
341-
* @return a byte array containing the key
342-
*/
343-
public byte[] getKey() {
344-
return key;
345-
}
335+
public static AES getAes() {
336+
return aes;
337+
}
346338

347-
/**
339+
/**
348340
* Returns a friendly description of this BLDevice
349341
* @return a String
350342
*/
@@ -381,39 +373,13 @@ public boolean auth() throws IOException {
381373
return false;
382374
}
383375

384-
log.debug("auth recv data bytes (" + data.length +") after initial req: {}", DatatypeConverter.printHexBinary(data));
385-
386-
log.debug("auth Getting encrypted data from 0x38 to the end");
387-
388-
byte[] encData = subbytes(data, 0x38, data.length);
389-
390-
log.debug("auth encDataLen=" + encData.length);
391-
392-
byte[] newBytes = null;
393-
if(encData.length > 0) {
394-
int numpad = encData.length % 16;
395-
if(numpad == 0)
396-
numpad = 16;
397-
newBytes = new byte[encData.length+numpad];
398-
for(int i = 0; i < newBytes.length; i++) {
399-
if(i < encData.length)
400-
newBytes[i] = encData[i];
401-
else
402-
newBytes[i] = 0x00;
403-
}
404-
}
405-
406-
log.debug("auth padded encoded bytes from initial req: {}", DatatypeConverter.printHexBinary(newBytes));
407-
408-
log.debug("auth Creating AES instance with initial iv, key");
409-
410-
AES aes = new AES(INITIAL_IV, INITIAL_KEY);
376+
log.debug("auth recv encrypted data bytes (" + data.length +") after initial req: {}", DatatypeConverter.printHexBinary(data));
411377

412378
byte[] payload = null;
413379
try {
414380
log.debug("auth Decrypting encrypted data");
415381

416-
payload = aes.decrypt(newBytes);
382+
payload = decryptFromDeviceMessage(data);
417383

418384
log.debug("auth Decrypted. len=" + payload.length);
419385

@@ -435,6 +401,8 @@ public boolean auth() throws IOException {
435401
return false;
436402
}
437403

404+
aes = new AES(iv, key);
405+
438406
log.debug("auth Getting ID from 0x00 to 0x04");
439407

440408
id = subbytes(payload, 0x00, 0x04);
@@ -886,6 +854,36 @@ public static byte[] subbytesTillNull(byte[] data, int offset) {
886854
return out;
887855
}
888856

857+
/**
858+
* Get Payload without header and padded for decryption.
859+
*
860+
* @param data the encrypted data message from the device and includes the header
861+
* @return Payload bytes without the header and padded to modulo 16
862+
*/
863+
public static byte[] getRawPayloadBytesPadded(byte[] data) {
864+
byte[] encData = subbytes(data, BLDevice.DEFAULT_BYTES_SIZE, data.length);
865+
byte[] newBytes = null;
866+
if(encData.length > 0) {
867+
int numpad = encData.length % 16;
868+
if(numpad == 0)
869+
numpad = 16;
870+
newBytes = new byte[encData.length+numpad];
871+
for(int i = 0; i < newBytes.length; i++) {
872+
if(i < encData.length)
873+
newBytes[i] = encData[i];
874+
else
875+
newBytes[i] = 0x00;
876+
}
877+
}
878+
return newBytes;
879+
}
880+
881+
protected static byte[] decryptFromDeviceMessage(byte[] encData) throws Exception {
882+
byte[] encPL = getRawPayloadBytesPadded(encData);
883+
byte[] pl = aes.decrypt(encPL);
884+
885+
return pl;
886+
}
889887
/**
890888
* Picks bytes from start-set to the end-set in a bytes array
891889
*

src/main/java/com/github/mob41/blapi/MP1Device.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import com.github.mob41.blapi.mac.Mac;
4141
import com.github.mob41.blapi.pkt.CmdPayload;
4242
import com.github.mob41.blapi.pkt.Payload;
43-
import com.github.mob41.blapi.pkt.auth.AES;
4443

4544
public class MP1Device extends BLDevice {
4645

@@ -118,7 +117,7 @@ public byte[] getData() {
118117

119118
});
120119

121-
log.debug("Received set power bytes: " + packet.getData());
120+
log.debug("Received set power bytes: " + DatatypeConverter.printHexBinary(packet.getData()));
122121
}
123122

124123
public boolean getStateByIndex(int index) throws Exception{
@@ -175,8 +174,7 @@ public byte[] getData() {
175174
int err = data[0x22] | (data[0x23] << 8);
176175

177176
if (err == 0) {
178-
AES aes = new AES(getIv(), getKey());
179-
byte[] pl = aes.decrypt(data);
177+
byte[] pl = decryptFromDeviceMessage(data);
180178
byte state = 0;
181179
if (pl[0x3c] >= 48 && pl[0x3c] <= 57) {
182180
String decodeValue1;

src/main/java/com/github/mob41/blapi/RM2Device.java

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.net.DatagramPacket;
3333

3434
import com.github.mob41.blapi.mac.Mac;
35-
import com.github.mob41.blapi.pkt.auth.AES;
3635
import com.github.mob41.blapi.pkt.cmd.rm2.CheckDataCmdPayload;
3736
import com.github.mob41.blapi.pkt.cmd.rm2.EnterLearnCmdPayload;
3837
import com.github.mob41.blapi.pkt.cmd.rm2.RMTempCmdPayload;
@@ -88,11 +87,7 @@ public byte[] checkData() throws Exception {
8887
int err = data[0x22] | (data[0x23] << 8);
8988

9089
if (err == 0) {
91-
AES aes = new AES(getIv(), getKey());
92-
byte[] encData = subbytes(data, 0x38, data.length);
93-
94-
encData = chgLen(encData, 1024);
95-
encData = aes.decrypt(encData);
90+
byte[] encData = decryptFromDeviceMessage(data);
9691

9792
return subbytes(encData, 0x04, encData.length);
9893
}
@@ -111,7 +106,8 @@ public byte[] checkData() throws Exception {
111106
*/
112107
public boolean enterLearning() throws IOException {
113108
EnterLearnCmdPayload cmdPayload = new EnterLearnCmdPayload();
114-
DatagramPacket packet = sendCmdPkt(10000, cmdPayload);
109+
@SuppressWarnings("unused")
110+
DatagramPacket packet = sendCmdPkt(10000, cmdPayload);
115111

116112
return true;
117113
}
@@ -132,13 +128,7 @@ public double getTemp() throws Exception {
132128
int err = data[0x22] | (data[0x23] << 8);
133129

134130
if (err == 0) {
135-
AES aes = new AES(getIv(), getKey());
136-
137-
byte[] encData = BLDevice.subbytes(data, 0x38, data.length);
138-
139-
encData = chgLen(encData, 1024);
140-
141-
byte[] pl = aes.decrypt(encData);
131+
byte[] pl = decryptFromDeviceMessage(data);
142132

143133
return (double) (pl[0x4] * 10 + pl[0x5]) / 10.0;
144134
} else {

src/main/java/com/github/mob41/blapi/SP2Device.java

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import com.github.mob41.blapi.mac.Mac;
4141
import com.github.mob41.blapi.pkt.CmdPayload;
4242
import com.github.mob41.blapi.pkt.Payload;
43-
import com.github.mob41.blapi.pkt.auth.AES;
4443

4544
public class SP2Device extends BLDevice {
4645

@@ -79,7 +78,7 @@ public byte[] getData() {
7978

8079
});
8180

82-
log.debug("Received set power bytes: " + packet.getData());
81+
log.debug("Received set power bytes: " + DatatypeConverter.printHexBinary(packet.getData()));
8382
}
8483

8584
public boolean getState() throws Exception {
@@ -105,28 +104,14 @@ public byte[] getData() {
105104
}
106105

107106
});
108-
byte[] encData = packet.getData();
107+
byte[] data = packet.getData();
109108

110-
log.debug("Packet received bytes: " + DatatypeConverter.printHexBinary(encData));
109+
log.debug("Packet received enctypted bytes: " + DatatypeConverter.printHexBinary(data));
111110

112-
int err = encData[0x22] | (encData[0x23] << 8);
111+
int err = data[0x22] | (data[0x23] << 8);
113112

114113
if (err == 0) {
115-
AES aes = new AES(getIv(), getKey());
116-
byte[] newBytes = null;
117-
if(encData.length > 0) {
118-
int numpad = encData.length % 16;
119-
if(numpad == 0)
120-
numpad = 16;
121-
newBytes = new byte[encData.length+numpad];
122-
for(int i = 0; i < newBytes.length; i++) {
123-
if(i < encData.length)
124-
newBytes[i] = encData[i];
125-
else
126-
newBytes[i] = 0x00;
127-
}
128-
}
129-
byte[] pl = aes.decrypt(newBytes);
114+
byte[] pl = decryptFromDeviceMessage(data);
130115
return pl[0x4] == 1 ? true : false;
131116
} else {
132117
log.warn("Received an error: " + Integer.toHexString(err) + " / " + err);

src/main/java/com/github/mob41/blapi/pkt/CmdPacket.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
import org.slf4j.Logger;
3434
import org.slf4j.LoggerFactory;
3535

36+
import com.github.mob41.blapi.BLDevice;
3637
import com.github.mob41.blapi.ex.BLApiRuntimeException;
3738
import com.github.mob41.blapi.mac.Mac;
38-
import com.github.mob41.blapi.pkt.auth.AES;
3939

4040
/**
4141
* This constructs a byte array with the format of a command to the Broadlink
@@ -48,8 +48,6 @@ public class CmdPacket implements Packet {
4848

4949
private static final Logger log = LoggerFactory.getLogger(CmdPacket.class);
5050

51-
private static final int DEFAULT_BYTES_SIZE = 0x38; // 56-bytes
52-
5351
private final byte[] data;
5452

5553
/**
@@ -87,7 +85,7 @@ public CmdPacket(Mac targetMac, int count, byte[] id, byte[] iv, byte[] key, Cmd
8785
log.debug("New count: " + count + " (added by 1)");
8886
log.debug("Creating byte array with data");
8987

90-
headerdata = new byte[DEFAULT_BYTES_SIZE];
88+
headerdata = new byte[BLDevice.DEFAULT_BYTES_SIZE];
9189
for (int i = 0; i < headerdata.length; i++) {
9290
headerdata[i] = 0x00;
9391
}
@@ -149,14 +147,11 @@ public CmdPacket(Mac targetMac, int count, byte[] id, byte[] iv, byte[] key, Cmd
149147
headerdata[0x35] = (byte) (checksumpayload >> 8);
150148

151149
log.debug("Un-encrypted payload checksum: " + Integer.toHexString(checksumpayload));
152-
log.debug("Creating AES instance with provided key {}, iv {}", key, iv);
153-
154-
AES aes = new AES(iv, key);
155150

156151
try {
157152
log.debug("Encrypting payload");
158153

159-
payload = aes.encrypt(payloadPad);
154+
payload = BLDevice.getAes().encrypt(payloadPad);
160155
log.debug("Encrypted payload bytes: {}", DatatypeConverter.printHexBinary(payload));
161156

162157
log.debug("Encrypted. len=" + payload.length);
@@ -165,14 +160,14 @@ public CmdPacket(Mac targetMac, int count, byte[] id, byte[] iv, byte[] key, Cmd
165160
throw new BLApiRuntimeException("Cannot encrypt payload", e);
166161
}
167162

168-
data = new byte[DEFAULT_BYTES_SIZE + payload.length];
163+
data = new byte[BLDevice.DEFAULT_BYTES_SIZE + payload.length];
169164

170165
for (int i = 0; i < headerdata.length; i++) {
171166
data[i] = headerdata[i];
172167
}
173168

174169
for (int i = 0; i < payload.length; i++) {
175-
data[i + DEFAULT_BYTES_SIZE] = payload[i];
170+
data[i + BLDevice.DEFAULT_BYTES_SIZE] = payload[i];
176171
}
177172

178173
log.debug("Running whole packet checksum");
@@ -181,7 +176,7 @@ public CmdPacket(Mac targetMac, int count, byte[] id, byte[] iv, byte[] key, Cmd
181176
for (int i = 0; i < data.length; i++) {
182177
checksumpkt = checksumpkt + Byte.toUnsignedInt(data[i]);
183178
checksumpkt = checksumpkt & 0xffff;
184-
log.debug("index: " + i + ", data byte: " + Byte.toUnsignedInt(data[i]) + ", checksum: " + checksumpkt);
179+
// log.debug("index: " + i + ", data byte: " + Byte.toUnsignedInt(data[i]) + ", checksum: " + checksumpkt);
185180
}
186181

187182
log.debug("Whole packet checksum: " + Integer.toHexString(checksumpkt));

0 commit comments

Comments
 (0)