use of org.spongycastle.crypto.engines.XTEAEngine in project fitness-app by seemoo-lab.
the class Firmware method rebootToBSLold.
public static String rebootToBSLold(Activity activity) throws UnsupportedEncodingException {
/*int headerlength = 14;
int inlength = 0;
int plainlength = 0;
int trailerlenght = 11;*/
String outStr = "";
/*File bslupdate = new File("/sdcard/788-bsl-plain.bin");
byte[] rawInput = {0} ; //ExternalStorage.loadByteArray("/sdcard/788-bsl-plain.bin", activity);
try {
rawInput = fullyReadFileToBytes(bslupdate);
//rawInput = ExternalStorage.loadByteArray("fwup-bsl-plain.bin",activity);
}catch(IOException e) {
}
byte[] header = new byte[headerlength];
byte[] trailer = new byte[trailerlenght];
inlength = rawInput.length;
plainlength = inlength - headerlength-trailerlenght;
byte[] plain = new byte[plainlength];
System.arraycopy(rawInput, 0, header, 0, headerlength);
System.arraycopy(rawInput, headerlength, plain, 0, plainlength);
System.arraycopy(rawInput, inlength-trailerlenght, trailer,0,trailerlenght);
// get the nonce from the dump
byte[] nonce = Arrays.copyOfRange(rawInput, 6, 10);
//compute the initial counter value using the nonce
byte[] counter = computeCounter(nonce);
// use the XTEA block cipher in counter mode (CTR)
SICBlockCipher cipher = new SICBlockCipher(new XTEAEngine());
// initialize using the key and the initial counter value.
cipher.init(true,new ParametersWithIV(new KeyParameter(ConstantValues.FITBIT_KEY), counter));
byte[] encrypted = new byte[plainlength];
//decrypt the encrypted part of the megadump, that is starting after byte 16
cipher.processBytes(plain, 0, plainlength, encrypted, 0);
//Log.e(TAG, "Decryped Dump");
String strenc = toHexString(encrypted);
Log.e(TAG, strenc);
byte[] out = new byte[inlength];
System.arraycopy(header, 0, out, 0, headerlength);
System.arraycopy(encrypted, 0, out, headerlength, encrypted.length);
byte[] cmac = calculateCMAC(nonce, plain, plainlength);
System.arraycopy(cmac, 0, out, headerlength + encrypted.length, cmac.length);
System.arraycopy(header, headerlength - 4, out, headerlength + encrypted.length + cmac.length, 3);*/
int bslHeaderLength = ConstantValues.REBOOT_TO_BSL_HEADER.length;
int bslDataLength = ConstantValues.REBOOT_TO_BSL_DATA.length;
byte[] command = new byte[bslHeaderLength + bslDataLength];
byte[] nonce = Arrays.copyOfRange(ConstantValues.REBOOT_TO_BSL_HEADER, 6, 10);
// compute the initial counter value using the nonce
// Crypto.computeCounter(nonce);
byte[] counter = { 0 };
// use the XTEA block cipher in counter mode (CTR)
SICBlockCipher cipher = new SICBlockCipher(new XTEAEngine());
// initialize using the key and the initial counter value.
cipher.init(true, new ParametersWithIV(new KeyParameter(Utilities.hexStringToByteArray(AuthValues.ENCRYPTION_KEY)), counter));
byte[] encrypted = new byte[bslDataLength];
// decrypt the encrypted part of the megadump, that is starting after byte 16
cipher.processBytes(command, 0, bslDataLength, encrypted, 0);
System.arraycopy(ConstantValues.REBOOT_TO_BSL_HEADER, 0, command, 0, bslHeaderLength);
System.arraycopy(encrypted, 0, command, bslHeaderLength, bslDataLength);
outStr = Utilities.byteArrayToHexString(command);
return outStr.toLowerCase();
}
use of org.spongycastle.crypto.engines.XTEAEngine in project fitness-app by seemoo-lab.
the class Crypto method encryptDump.
/*
Fitbit Flex/One/Charge firmware uses XTEA in EAX mode, we encrypt according to this.
TODO: if we find a vulnerability for AES trackers, this method should also be able to use AES/EAX...
Length fields must match, otherwise result can become null ...
*/
public static String encryptDump(byte[] dump, Activity activity) throws InvalidCipherTextException {
int headerlength = 14;
int inlength = 0;
int plainlength = 0;
int trailerlenght = 11;
String outStr = "";
byte[] header = new byte[headerlength];
byte[] trailer = new byte[trailerlenght];
inlength = dump.length;
plainlength = inlength - headerlength - trailerlenght;
byte[] plain = new byte[plainlength];
System.arraycopy(dump, 0, header, 0, headerlength);
System.arraycopy(dump, headerlength, plain, 0, plainlength);
System.arraycopy(dump, inlength - trailerlenght, trailer, 0, trailerlenght);
// Set Crypt-Byte in header
header[4] = (byte) 0x01;
// Nonce should not be zero... //TODO make nonce random
// header[6] = (byte) 0xab;
// header[7] = (byte) 0xcd;
// get the nonce from the dump
byte[] nonce = Arrays.copyOfRange(header, 6, 10);
// cmac (tag) length in bytes
int mac_len = 8 * 8;
XTEAEngine engine = new XTEAEngine();
EAXBlockCipher eax = new EAXBlockCipher(engine);
Log.e(TAG, "key: " + getKey());
Log.e(TAG, "nonce: " + Utilities.byteArrayToHexString(nonce));
AEADParameters params = new AEADParameters(new KeyParameter(getKey()), mac_len, nonce, null);
// TODO switch true to false here to implement a decryption method, apply it to microdumps/megadumps
eax.init(true, params);
byte[] result = new byte[eax.getOutputSize(plainlength)];
int resultlength = eax.processBytes(plain, 0, plainlength, result, 0);
eax.doFinal(result, resultlength);
byte[] out = new byte[inlength];
System.arraycopy(header, 0, out, 0, headerlength);
System.arraycopy(result, 0, out, headerlength, result.length);
System.arraycopy(header, headerlength - 4, out, headerlength + result.length, 3);
outStr = Utilities.byteArrayToHexString(out);
return outStr;
}
use of org.spongycastle.crypto.engines.XTEAEngine in project fitness-app by seemoo-lab.
the class AuthenticationInteraction method generateCMAC.
/**
* Calculates the cmac.
*
* @param sequenceNumber The sequence number to calculate the cmac with.
* @param authenticationKey The authentication key to calculate the cmac with.
* @return The calculated cmac.
*/
private String generateCMAC(byte[] sequenceNumber, String authenticationKey) {
String seqNum = Utilities.byteArrayToHexString(sequenceNumber);
if (seqNum.length() > 4 && seqNum.substring(0, 4).equals(ConstantValues.AUTHENTICATION_CHALLENGE)) {
seqNum = seqNum.substring(20);
seqNum = Utilities.rotateBytes(seqNum);
byte[] authKey = Utilities.hexStringToByteArray(authenticationKey);
BlockCipher cypher;
switch(deviceType) {
case 1:
cypher = new XTEAEngine();
break;
case 2:
cypher = new AESEngine();
break;
default:
cypher = null;
Log.e(TAG, "Error: AuthenticationInteraction key not available!");
}
if (cypher != null && authKey != null) {
CMac mac = new CMac(cypher, 64);
mac.init(new KeyParameter(authKey));
byte[] counter = Utilities.intToByteArray(Integer.parseInt(seqNum, 16));
mac.update(counter, 0, 4);
byte[] bArr = new byte[8];
mac.doFinal(bArr, 0);
return Utilities.byteArrayToHexString(bArr);
}
}
return null;
}
Aggregations