Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,14 @@ public static byte compare(byte[] buf, short lhs, short rhs) {
return KMInteger.unsignedByteArrayCompare(buf, lhs, buf, rhs, (short) 8);
}

public static void shiftLeft(byte[] buf, short start, short count) {
short index = 0;
while (index < count) {
shiftLeft(buf, start);
index++;
}
}

public static void shiftLeft(byte[] buf, short start) {
byte index = 7;
byte carry = 0;
Expand Down Expand Up @@ -343,7 +351,9 @@ public static void add(byte[] buf, short op1, short op2, short result) {
byte carry = 0;
short tmp;
while (index >= 0) {
tmp = (short) (buf[(short) (op1 + index)] + buf[(short) (op2 + index)] + carry);
tmp =
(short) ((buf[(short) (op1 + index)] & 0xFF) +
(buf[(short) (op2 + index)] & 0xFF) + carry);
carry = 0;
if (tmp > 255) {
carry = 1; // max unsigned byte value is 255
Expand Down Expand Up @@ -409,4 +419,19 @@ public static short getLeapYrIndex(boolean from2020, short yrsCount) {
return -1;
}

}
//i * 1000 = (i << 9) + (i << 8) + (i << 7) + (i << 6) + (i << 5) + ( i << 3)
public static void convertToMilliseconds(byte[] buf, short inputOff, short outputOff,
short scratchPadOff) {
byte[] shiftPos = {9, 8, 7, 6, 5, 3};
short index = 0;
while (index < (short) (shiftPos.length)) {
Util.arrayCopyNonAtomic(buf, inputOff, buf, scratchPadOff, (short) 8);
shiftLeft(buf, scratchPadOff, shiftPos[index]);
Util.arrayCopyNonAtomic(buf, outputOff, buf, (short) (scratchPadOff + 8), (short) 8);
add(buf, scratchPadOff, (short) (8 + scratchPadOff), (short) (16 + scratchPadOff));
Util.arrayCopyNonAtomic(buf, (short) (scratchPadOff + 16), buf, outputOff, (short) 8);
Util.arrayFillNonAtomic(buf, scratchPadOff, (short) 24, (byte) 0);
index++;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,14 @@ public static byte compare(byte[] buf, short lhs, short rhs) {
return KMInteger.unsignedByteArrayCompare(buf, lhs, buf, rhs, (short) 8);
}

public static void shiftLeft(byte[] buf, short start, short count) {
short index = 0;
while (index < count) {
shiftLeft(buf, start);
index++;
}
}

public static void shiftLeft(byte[] buf, short start) {
byte index = 7;
byte carry = 0;
Expand Down Expand Up @@ -343,7 +351,9 @@ public static void add(byte[] buf, short op1, short op2, short result) {
byte carry = 0;
short tmp;
while (index >= 0) {
tmp = (short) (buf[(short) (op1 + index)] + buf[(short) (op2 + index)] + carry);
tmp =
(short) ((buf[(short) (op1 + index)] & 0xFF) +
(buf[(short) (op2 + index)] & 0xFF) + carry);
carry = 0;
if (tmp > 255) {
carry = 1; // max unsigned byte value is 255
Expand Down Expand Up @@ -409,4 +419,20 @@ public static short getLeapYrIndex(boolean from2020, short yrsCount) {
return -1;
}

}
// i * 1000 = (i << 9) + (i << 8) + (i << 7) + (i << 6) + (i << 5) + ( i << 3)
public static void convertToMilliseconds(byte[] buf, short inputOff, short outputOff,
short scratchPadOff) {
byte[] shiftPos = {9, 8, 7, 6, 5, 3};
short index = 0;
while (index < (short) (shiftPos.length)) {
Util.arrayCopyNonAtomic(buf, inputOff, buf, scratchPadOff, (short) 8);
shiftLeft(buf, scratchPadOff, shiftPos[index]);
Util.arrayCopyNonAtomic(buf, outputOff, buf, (short) (scratchPadOff + 8), (short) 8);
add(buf, scratchPadOff, (short) (8 + scratchPadOff), (short) (16 + scratchPadOff));
Util.arrayCopyNonAtomic(buf, (short) (scratchPadOff + 16), buf, outputOff, (short) 8);
Util.arrayFillNonAtomic(buf, scratchPadOff, (short) 24, (byte) 0);
index++;
}
}

}
2 changes: 2 additions & 0 deletions Applet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ which serves to intermediate between Android Keystore and this applet.
- Install Javacard 3.0.5 classic sdk.
- set JC_HOME_SIMULATOR environment variable to the installed sdk.
- Give ant build from Applet folder.
- Download [gpapi-upgrade.jar](https://globalplatform.wpengine.com/specs-library/globalplatform-card-api-org-globalplatform-upgrade-v1/) and copy inside lib folder of both AndroidSEProvider and JCardSimProvider to resolve the compilation errors.

6 changes: 6 additions & 0 deletions Applet/src/com/android/javacard/keymaster/KMArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ public void add(short index, short objPtr) {
(short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2)),
objPtr);
}

public void deleteLastEntry() {
short len = length();
Util.setShort(heap, (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + 2), (short) (len -1));
}


public short get(short index) {
short len = length();
Expand Down
3 changes: 1 addition & 2 deletions Applet/src/com/android/javacard/keymaster/KMEnumTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ public static void create() {
new byte[]{RSA, DES, EC, AES, HMAC},
new byte[]{P_224, P_256, P_384, P_521},
new byte[]{STANDALONE, REQUIRES_FILE_SYSTEM},
new byte[]{USER_AUTH_NONE, PASSWORD, FINGERPRINT, (byte) (PASSWORD & FINGERPRINT),
ANY},
new byte[]{USER_AUTH_NONE, PASSWORD, FINGERPRINT, BOTH, ANY},
new byte[]{GENERATED, DERIVED, IMPORTED, UNKNOWN, SECURELY_IMPORTED},
new byte[]{SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX}
};
Expand Down
9 changes: 9 additions & 0 deletions Applet/src/com/android/javacard/keymaster/KMInteger.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,15 @@ public short value(byte[] dest, short destOff) {
return length();
}

public short toLittleEndian(byte[] dest, short destOff) {
short index = (short) (length() - 1);
while (index >= 0) {
dest[destOff++] = heap[(short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE + index)];
index--;
}
return length();
}

public short getShort() {
return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE + 2));
}
Expand Down
13 changes: 12 additions & 1 deletion Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static short exp(short tagType) {
if (!validateTagType(tagType)) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
short arrPtr = KMArray.exp(KMType.INTEGER_TYPE);
short arrPtr = KMArray.exp(KMInteger.exp());
short ptr = instance(TAG_TYPE, (short) 6);
Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), tagType);
Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), INVALID_TAG);
Expand Down Expand Up @@ -134,6 +134,17 @@ private static boolean validateTagType(short tagType) {
return (tagType == ULONG_ARRAY_TAG) || (tagType == UINT_ARRAY_TAG);
}

public boolean contains(short tagValue) {
short index = 0;
while (index < length()) {
if (KMInteger.compare(tagValue, get(index)) == 0) {
return true;
}
index++;
}
return false;
}

public static boolean contains(short tagId, short tagValue, short params) {
short tag =
KMKeyParameters.findTag(KMType.UINT_ARRAY_TAG, tagId, params);
Expand Down
4 changes: 3 additions & 1 deletion Applet/src/com/android/javacard/keymaster/KMIntegerTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public class KMIntegerTag extends KMTag {
ACTIVE_DATETIME,
ORIGINATION_EXPIRE_DATETIME,
USAGE_EXPIRE_DATETIME,
CREATION_DATETIME
CREATION_DATETIME,
// Custom tag.
AUTH_TIMEOUT_MILLIS
};

private KMIntegerTag() {
Expand Down
70 changes: 70 additions & 0 deletions Applet/src/com/android/javacard/keymaster/KMKeyParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
* arrayPtr is a pointer to array with any KMTag subtype instances.
*/
public class KMKeyParameters extends KMType {


private static short[] customTags;

private static KMKeyParameters prototype;

Expand Down Expand Up @@ -211,6 +214,9 @@ public static short makeHwEnforced(short keyParamsPtr, byte origin,
.instance(KMType.UINT_TAG, KMType.BOOT_PATCH_LEVEL, bootPatchObjPtr);
Util.setShort(scratchPad, arrInd, bootPatchTag);
arrInd += 2;
// Add custom tags at the end of the array. So it becomes easy to
// delete them when sending key characteristics back to HAL.
arrInd = addCustomTags(keyParamsPtr, scratchPad, arrInd);
return createKeyParameters(scratchPad, (short) (arrInd / 2));
}

Expand Down Expand Up @@ -318,4 +324,68 @@ public static short createKeyParameters(byte[] ptrArr, short len) {
}
return KMKeyParameters.instance(arrPtr);
}

private static short[] getCustomTags() {
if (customTags == null) {
customTags = new short[] {
KMType.ULONG_TAG, KMType.AUTH_TIMEOUT_MILLIS,
};
}
return customTags;
}

public static short addCustomTags(short keyParams, byte[] scratchPad, short offset) {
short[] customTags = getCustomTags();
short index = 0;
short tagPtr;
short len = (short) customTags.length;
short tagType;
while (index < len) {
tagType = customTags[(short) (index + 1)];
switch(tagType) {
case KMType.AUTH_TIMEOUT_MILLIS:
short authTimeOutTag =
KMKeyParameters.cast(keyParams).findTag(KMType.UINT_TAG, KMType.AUTH_TIMEOUT);
if (authTimeOutTag != KMType.INVALID_VALUE) {
tagPtr = createAuthTimeOutMillisTag(authTimeOutTag, scratchPad, offset);
Util.setShort(scratchPad, offset, tagPtr);
offset += 2;
}
break;
default:
break;
}
index += 2;
}
return offset;
}

public void deleteCustomTags() {
short arrPtr = getVals();
short[] customTags = getCustomTags();
short index = (short) (customTags.length - 1);
short obj;
while (index >= 0) {
obj = findTag(customTags[(short) (index - 1)], customTags[index]);
if (obj != KMType.INVALID_VALUE) {
KMArray.cast(arrPtr).deleteLastEntry();
}
index -= 2;
}
}

public static short createAuthTimeOutMillisTag(short authTimeOutTag, byte[] scratchPad, short offset) {
short authTime = KMIntegerTag.cast(authTimeOutTag).getValue();
Util.arrayFillNonAtomic(scratchPad, offset, (short) 40, (byte) 0);
Util.arrayCopyNonAtomic(
KMInteger.cast(authTime).getBuffer(),
KMInteger.cast(authTime).getStartOff(),
scratchPad,
(short) (offset + 8 - KMInteger.cast(authTime).length()),
KMInteger.cast(authTime).length());
KMUtils.convertToMilliseconds(scratchPad, offset, (short) (offset + 8), (short) (offset + 16));
return KMIntegerTag.instance(KMType.ULONG_TAG, KMType.AUTH_TIMEOUT_MILLIS,
KMInteger.uint_64(scratchPad, (short) (offset + 8)));
}

}
Loading