mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-10 09:01:55 +01:00
[Huawei] Add new Crypto and authMode
This commit is contained in:
parent
f759072a7c
commit
86461ada1a
@ -24,6 +24,7 @@ import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
@ -78,15 +79,17 @@ public class HuaweiCrypto {
|
||||
public static final long ENCRYPTION_COUNTER_MAX = 0xFFFFFFFF;
|
||||
|
||||
protected int authVersion;
|
||||
protected boolean isHiChainLite = false;
|
||||
protected int authMode;
|
||||
protected byte authAlgo;
|
||||
|
||||
public HuaweiCrypto(int authVersion) {
|
||||
this.authVersion = authVersion;
|
||||
}
|
||||
|
||||
public HuaweiCrypto(int authVersion, boolean isHiChainLite) {
|
||||
public HuaweiCrypto(int authVersion, byte authAlgo, int authMode) {
|
||||
this(authVersion);
|
||||
this.isHiChainLite = isHiChainLite;
|
||||
this.authMode = authMode;
|
||||
this.authAlgo = authAlgo;
|
||||
}
|
||||
|
||||
public static byte[] generateNonce() {
|
||||
@ -115,26 +118,27 @@ public class HuaweiCrypto {
|
||||
return CryptoUtils.calcHmacSha256(digestStep1, nonce);
|
||||
}
|
||||
|
||||
public byte[] computeDigestHiChainLite(byte[] message, byte[] key, byte[] nonce) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
public byte[] computeDigestHiChainLite(byte[] message, byte[] key, byte[] nonce) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
|
||||
byte[] digestStep1;
|
||||
byte[] hashKey = CryptoUtils.digest(key);
|
||||
byte[] digestSecret = getDigestSecret();
|
||||
for (int i = 0; i < digestSecret.length; i++) {
|
||||
digestSecret[i] = (byte) (((0xFF & hashKey[i]) ^ (digestSecret[i] & 0xFF)) & 0xFF);
|
||||
}
|
||||
// 2 possibilities:
|
||||
// - type 1 : Pbk (SDK_INT>= 0x17) fallback to MacSha
|
||||
// - type 2 : MacSha
|
||||
// We force type 2 to avoid a new calculation
|
||||
byte[] msgToDigest = ByteBuffer.allocate(18)
|
||||
.put(digestSecret)
|
||||
.put(message)
|
||||
.array();
|
||||
byte[] digestStep1 = CryptoUtils.calcHmacSha256(msgToDigest, nonce) ;
|
||||
if (authAlgo == 0x01) {
|
||||
digestStep1 = CryptoUtils.pbkdf2Sha256(msgToDigest, nonce, 0x3e8, 0x100);
|
||||
} else {
|
||||
digestStep1 = CryptoUtils.calcHmacSha256(msgToDigest, nonce);
|
||||
}
|
||||
return CryptoUtils.calcHmacSha256(digestStep1, nonce);
|
||||
}
|
||||
|
||||
public byte[] digestChallenge(byte[] secretKey, byte[] nonce) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
if (isHiChainLite) {
|
||||
public byte[] digestChallenge(byte[] secretKey, byte[] nonce) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
|
||||
if (authMode == 0x02) {
|
||||
if (secretKey == null)
|
||||
return null;
|
||||
if (authVersion == 0x02) {
|
||||
@ -149,8 +153,8 @@ public class HuaweiCrypto {
|
||||
return computeDigest(MESSAGE_CHALLENGE, nonce);
|
||||
}
|
||||
|
||||
public byte[] digestResponse(byte[] secretKey, byte[] nonce) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
if (isHiChainLite) {
|
||||
public byte[] digestResponse(byte[] secretKey, byte[] nonce) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
|
||||
if (authMode == 0x02) {
|
||||
if (secretKey == null)
|
||||
return null;
|
||||
if (authVersion == 0x02) {
|
||||
|
@ -55,6 +55,7 @@ public class HuaweiPacket {
|
||||
protected byte[] pinCode = null;
|
||||
|
||||
protected byte interval;
|
||||
protected byte authAlgo;
|
||||
|
||||
public void setAuthVersion(byte authVersion) {
|
||||
this.authVersion = authVersion;
|
||||
@ -134,6 +135,14 @@ public class HuaweiPacket {
|
||||
public void setEncryptionCounter(long counter) {
|
||||
this.encryptionCounter = counter;
|
||||
}
|
||||
|
||||
public void setAuthAlgo(byte authAlgo) {
|
||||
this.authAlgo = authAlgo;
|
||||
}
|
||||
|
||||
public byte getAuthAlgo () {
|
||||
return this.authAlgo;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class ParseException extends Exception {
|
||||
|
@ -625,8 +625,7 @@ public class DeviceConfig {
|
||||
public Request(
|
||||
ParamsProvider paramsProvider,
|
||||
byte[] challenge,
|
||||
byte[] nonce,
|
||||
boolean isHiChainLite
|
||||
byte[] nonce
|
||||
) {
|
||||
super(paramsProvider);
|
||||
|
||||
@ -636,8 +635,8 @@ public class DeviceConfig {
|
||||
this.tlv = new HuaweiTLV()
|
||||
.put(0x01, challenge)
|
||||
.put(0x02, nonce);
|
||||
if (isHiChainLite)
|
||||
this.tlv.put(0x03, (byte)0x02); // Force type 2
|
||||
if (paramsProvider.getAuthMode() == 0x02)
|
||||
this.tlv.put(0x03, paramsProvider.getAuthAlgo());
|
||||
this.isEncrypted = false;
|
||||
this.complete = true;
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ public class HuaweiSupportProvider {
|
||||
protected void initializeDeviceHiChainLiteMode(Request linkParamsReq) {
|
||||
try {
|
||||
createSecretKey();
|
||||
GetAuthRequest authReq = new GetAuthRequest(this, linkParamsReq, true);
|
||||
GetAuthRequest authReq = new GetAuthRequest(this, linkParamsReq);
|
||||
GetBondParamsRequest bondParamsReq = new GetBondParamsRequest(this);
|
||||
GetBondRequest bondReq = new GetBondRequest(this);
|
||||
authReq.nextRequest(bondParamsReq);
|
||||
|
@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -36,9 +37,10 @@ public class GetAuthRequest extends Request {
|
||||
|
||||
protected final byte[] clientNonce;
|
||||
protected short authVersion;
|
||||
protected boolean isHiChainLite = false;
|
||||
protected byte authAlgo;
|
||||
protected byte[] doubleNonce;
|
||||
protected byte[] key = null;
|
||||
protected byte authMode;
|
||||
|
||||
public GetAuthRequest(HuaweiSupportProvider support,
|
||||
Request linkParamsReq) {
|
||||
@ -51,22 +53,17 @@ public class GetAuthRequest extends Request {
|
||||
.put(clientNonce)
|
||||
.array();
|
||||
this.authVersion = paramsProvider.getAuthVersion();
|
||||
}
|
||||
|
||||
public GetAuthRequest(HuaweiSupportProvider support,
|
||||
Request linkParamsReq,
|
||||
boolean isHiChainLite) {
|
||||
this(support, linkParamsReq);
|
||||
this.isHiChainLite = isHiChainLite;
|
||||
this.authAlgo = paramsProvider.getAuthAlgo();
|
||||
this.authMode = paramsProvider.getAuthMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<byte[]> createRequest() throws RequestCreationException {
|
||||
huaweiCrypto = new HuaweiCrypto(authVersion, isHiChainLite);
|
||||
huaweiCrypto = new HuaweiCrypto(authVersion, authAlgo, authMode);
|
||||
byte[] nonce;
|
||||
|
||||
try {
|
||||
if (isHiChainLite) {
|
||||
if (authMode == 0x02) {
|
||||
key = paramsProvider.getPinCode();
|
||||
if (authVersion == 0x02)
|
||||
key = paramsProvider.getSecretKey();
|
||||
@ -78,10 +75,10 @@ public class GetAuthRequest extends Request {
|
||||
byte[] challenge = huaweiCrypto.digestChallenge(key, doubleNonce);
|
||||
if (challenge == null)
|
||||
throw new RequestCreationException("Challenge null");
|
||||
return new DeviceConfig.Auth.Request(paramsProvider, challenge, nonce, isHiChainLite).serialize();
|
||||
return new DeviceConfig.Auth.Request(paramsProvider, challenge, nonce).serialize();
|
||||
} catch (HuaweiPacket.CryptoException e) {
|
||||
throw new RequestCreationException(e);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException e) {
|
||||
throw new RequestCreationException("Digest exception", e);
|
||||
}
|
||||
}
|
||||
@ -105,7 +102,7 @@ public class GetAuthRequest extends Request {
|
||||
+ StringUtils.bytesToHex(expectedAnswer)
|
||||
);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException e) {
|
||||
throw new ResponseParseException("Challenge response digest exception");
|
||||
}
|
||||
}
|
||||
|
@ -82,5 +82,7 @@ public class GetLinkParamsRequest extends Request {
|
||||
paramsProvider.setAuthVersion(((LinkParams.Response) receivedPacket).authVersion);
|
||||
|
||||
this.bondState = ((LinkParams.Response) receivedPacket).bondState;
|
||||
|
||||
paramsProvider.setAuthAlgo(((LinkParams.Response) receivedPacket).authAlgo);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user