Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
poschi3 committed Jun 6, 2020
1 parent 8010d15 commit ec592fb
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.coralibre.android.sdk.internal.crypto;

public class ByteHelper {

// See https://stackoverflow.com/a/11208685/499842
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.coralibre.android.sdk.internal.crypto.ppcp.AssociatedEncryptedMetadataKey;
import org.coralibre.android.sdk.internal.crypto.ppcp.AssociatedMetadata;
import org.coralibre.android.sdk.internal.crypto.ppcp.CryptoModule;
import org.coralibre.android.sdk.internal.crypto.ppcp.ENNumber;
import org.coralibre.android.sdk.internal.crypto.ppcp.PaddedData;
import org.coralibre.android.sdk.internal.crypto.ppcp.RollingProximityIdentifier;
import org.coralibre.android.sdk.internal.crypto.ppcp.RollingProximityIdentifierKey;
Expand Down Expand Up @@ -105,16 +106,26 @@ public class CryptoModuleTests {

private static final byte[] AM_VAL_V3_2_MINUS16db = {(byte) 0b11100000, (byte) 0xF0, 0x00, 0x00};

private static final byte[] TEK_VAL2 = ByteHelper.hexStringToByteArray("2765f41dbaa6306a264391913bf48723");

private static final byte[] TEK_VAL2_RPIK = ByteHelper.hexStringToByteArray("34fbbd748ee78bb386d1bab2df7b4165");

private static final byte[] TEK_VAL2_RPI_1 = ByteHelper.hexStringToByteArray("31fc2cf219fe6dc6765d860e979ba9e5");

private static final byte[] TEK_VAL2_AEMK = ByteHelper.hexStringToByteArray("e01962eba7d4b5f40226e91ef9f6c050");

private static final byte[] TEK_VAL2_AEM = ByteHelper.hexStringToByteArray("10413a43");

@Test
public void testGenerateRPIK() throws Exception {
TemporaryExposureKey tek = new TemporaryExposureKey(new Pair<>(0L, TEK_VAL1));
TemporaryExposureKey tek = new TemporaryExposureKey(0L, TEK_VAL1);
RollingProximityIdentifierKey rpik = CryptoModule.generateRPIK(tek);
assertArrayEquals(RPIK_VAL1, rpik.getKey());
}

@Test
public void testGenerateAEMK() throws Exception {
TemporaryExposureKey tek = new TemporaryExposureKey(new Pair<>(0L, TEK_VAL1));
TemporaryExposureKey tek = new TemporaryExposureKey(0L, TEK_VAL1);
AssociatedEncryptedMetadataKey aemk = CryptoModule.generateAEMK(tek);
assertArrayEquals(AEMK_VAL1, aemk.getKey());
}
Expand All @@ -139,4 +150,23 @@ public void testEncryptDecryptAEM() throws Exception {
AssociatedMetadata decryptedAM = CryptoModule.decryptAEM(aem, rpi, aemk);
assertArrayEquals(am.getData(), decryptedAM.getData());
}

@Test
// See: https://github.com/corona-warn-app/cwa-app-android/issues/75#issuecomment-640114705
public void testRoundtripExample1() throws Exception {
TemporaryExposureKey tek = new TemporaryExposureKey(0L, TEK_VAL2);
RollingProximityIdentifierKey rpik = CryptoModule.generateRPIK(tek);
assertArrayEquals(TEK_VAL2_RPIK, rpik.getKey());
ENNumber enNumber = new ENNumber(2652091);
RollingProximityIdentifier rpi = CryptoModule.generateRPI(rpik, enNumber);
assertArrayEquals(TEK_VAL2_RPI_1, rpi.getData());

AssociatedEncryptedMetadataKey aemk = CryptoModule.generateAEMK(tek);
assertArrayEquals(TEK_VAL2_AEMK, aemk.getKey());

AssociatedEncryptedMetadata aem = new AssociatedEncryptedMetadata(TEK_VAL2_AEM);
AssociatedMetadata am = CryptoModule.decryptAEM(aem, rpi, aemk);
assertEquals(-14, am.getTransmitPowerLevel());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ public void testSetTEKWithENNumberTimestamp() {

@Test
public void testSetTEKFromRawData() {
TemporaryExposureKey tek = new TemporaryExposureKey(new Pair<>(RAW_INPUT_ENNUMBER_VAL1, TEK_VAL1));
TemporaryExposureKey tek = new TemporaryExposureKey(RAW_INPUT_ENNUMBER_VAL1, TEK_VAL1);
assertArrayEquals(TEK_VAL1, tek.getKey());
assertEquals(RAW_OUTPUT_ENNUMBER_VAL1, tek.getTimestamp().get());
}

@Test
public void testSetExactTimestamp() {
TemporaryExposureKey tek = new TemporaryExposureKey(new Pair<>(RAW_OUTPUT_ENNUMBER_VAL1, TEK_VAL1));
TemporaryExposureKey tek = new TemporaryExposureKey(RAW_OUTPUT_ENNUMBER_VAL1, TEK_VAL1);
assertArrayEquals(TEK_VAL1, tek.getKey());
assertEquals(RAW_OUTPUT_ENNUMBER_VAL1, tek.getTimestamp().get());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,20 @@ public static RollingProximityIdentifier generateRPI(RollingProximityIdentifierK
throws InvalidKeyException,
NoSuchPaddingException,
NoSuchAlgorithmException {
return generateRPI(rpik, getCurrentENNumber());
}

public static RollingProximityIdentifier generateRPI(RollingProximityIdentifierKey rpik, ENNumber enNumber)
throws InvalidKeyException,
NoSuchPaddingException,
NoSuchAlgorithmException {
SecretKeySpec keySpec = new SecretKeySpec(rpik.getKey(), "AES");
// normally ECB is a bad idea, but in this case we just want to encrypt a single block
@SuppressLint("GetInstance")
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);

PaddedData paddedData = new PaddedData(getCurrentENNumber());
PaddedData paddedData = new PaddedData(enNumber);
return new RollingProximityIdentifier(cipher.update(paddedData.getData()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public TemporaryExposureKey(ENNumber timestamp, byte[] value) {
System.arraycopy(value, 0, key, 0, TEK_LENGTH);
}

public TemporaryExposureKey(Pair<Long, byte[]> rawKey) {
this(new ENNumber(rawKey.first), rawKey.second);
public TemporaryExposureKey(long timestamp, byte[] rawKey) {
this(new ENNumber(timestamp), rawKey);
}

public ENNumber getTimestamp() {
Expand Down

0 comments on commit ec592fb

Please sign in to comment.