aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2023-09-26 22:37:48 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-09-26 22:37:48 +0000
commitf6f34c5a08ba7e6db669bdb4d65f8ce0c79bb983 (patch)
tree4f60a9ce6de621aa9720cd8b16d6184db78c2714
parenta2549ab421f2a737ef3b93e04977f10adf5e6eb4 (diff)
parent94791c41005eda91e56eab6f5a1a4bc2d3fca9f0 (diff)
downloadlibese-f6f34c5a08ba7e6db669bdb4d65f8ce0c79bb983.tar.gz
Merge "Support uint16/uint32 for ENUM Tag." into main am: 94791c4100
Original change: https://android-review.googlesource.com/c/platform/external/libese/+/2670815 Change-Id: I880fc97334a0f413120236cb0a2932a39c018257 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java80
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java12
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java46
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnumTag.java31
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java53
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMOperationState.java16
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMType.java15
7 files changed, 185 insertions, 68 deletions
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java
index dd05b13..406f707 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java
@@ -483,31 +483,51 @@ public class KMDecoder {
return arrPtr;
}
- private short decodeEnumTag(short exp) {
- readTagKey(KMEnumTag.cast(exp).getTagType());
+ private short createInstanceEnumType(short instanceType, byte[] buf, short offset, short len) {
+ byte type = KMType.getType(instanceType);
+ short ptr = KMType.INVALID_VALUE;
+ switch (type) {
+ case KMType.ENUM_TYPE:
+ ptr = KMEnum.instance(KMEnum.cast(instanceType).getEnumType(), buf, offset, len);
+ break;
+ case KMType.TAG_TYPE:
+ ptr = KMEnumTag.instance(scratchBuf[TAG_KEY_OFFSET], buf, offset, len);
+ break;
+ default:
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ }
+ return ptr;
+ }
+
+ private short decodeEnumAndCreateInstance(short instanceType) {
byte[] buffer = (byte[]) bufferRef[0];
- short startOff = scratchBuf[START_OFFSET];
- // Enum Tag value will always be integer with max 1 byte length.
- if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) {
+ short offset = scratchBuf[START_OFFSET];
+ if ((buffer[offset] & MAJOR_TYPE_MASK) != UINT_TYPE) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
- short len = (short) (buffer[startOff] & ADDITIONAL_MASK);
- byte enumVal = 0;
- if (len > UINT8_LENGTH) {
+ short addInfo = (short) (buffer[offset] & ADDITIONAL_MASK);
+ if (addInfo > UINT32_LENGTH) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
- if (len < UINT8_LENGTH) {
- enumVal = (byte) (len & ADDITIONAL_MASK);
- incrementStartOff((short) 1);
- } else if (len == UINT8_LENGTH) {
- incrementStartOff((short) 1);
- // startOff is incremented so update the startOff
- // with latest value before using it.
- startOff = scratchBuf[START_OFFSET];
- enumVal = buffer[startOff];
+ if (addInfo >= UINT8_LENGTH) {
incrementStartOff((short) 1);
+ offset = scratchBuf[START_OFFSET];
+ }
+ byte originalValue = buffer[offset];
+ if (addInfo < UINT8_LENGTH) {
+ // In this case additional info is the actual enum value.
+ buffer[offset] = (byte) addInfo;
}
- return KMEnumTag.instance(scratchBuf[TAG_KEY_OFFSET], enumVal);
+ short len = (short) ((addInfo > UINT8_LENGTH) ? ((addInfo == UINT32_LENGTH) ? 4 : 2) : 1);
+ short ptr = createInstanceEnumType(instanceType, buffer, offset, len);
+ buffer[offset] = originalValue;
+ incrementStartOff(len);
+ return ptr;
+ }
+
+ private short decodeEnumTag(short exp) {
+ readTagKey(KMEnumTag.cast(exp).getTagType());
+ return decodeEnumAndCreateInstance(exp);
}
private short decodeBoolTag(short exp) {
@@ -526,29 +546,7 @@ public class KMDecoder {
}
private short decodeEnum(short exp) {
- byte[] buffer = (byte[]) bufferRef[0];
- short startOff = scratchBuf[START_OFFSET];
- // Enum value will always be integer with max 1 byte length.
- if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) {
- ISOException.throwIt(ISO7816.SW_DATA_INVALID);
- }
- short len = (short) (buffer[startOff] & ADDITIONAL_MASK);
- byte enumVal;
- if (len > UINT8_LENGTH) {
- ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
- }
- if (len < UINT8_LENGTH) {
- enumVal = (byte) (len & ADDITIONAL_MASK);
- incrementStartOff((short) 1);
- } else {
- incrementStartOff((short) 1);
- // startOff is incremented so update the startOff
- // with latest value before using it.
- startOff = scratchBuf[START_OFFSET];
- enumVal = buffer[startOff];
- incrementStartOff((short) 1);
- }
- return KMEnum.instance(KMEnum.cast(exp).getEnumType(), enumVal);
+ return decodeEnumAndCreateInstance(exp);
}
private short decodeSimpleValue(short exp) {
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java
index 65394bd..2146c82 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java
@@ -396,11 +396,19 @@ public class KMEncoder {
private void encodeEnumTag(short obj) {
writeTag(KMEnumTag.cast(obj).getTagType(), KMEnumTag.cast(obj).getKey());
- writeByteValue(KMEnumTag.cast(obj).getValue());
+ encodeInteger(
+ KMEnumTag.cast(obj).getBuffer(),
+ KMEnumTag.cast(obj).length(),
+ KMEnumTag.cast(obj).getStartOffset(),
+ UINT_TYPE);
}
private void encodeEnum(short obj) {
- writeByteValue(KMEnum.cast(obj).getVal());
+ encodeInteger(
+ KMEnum.cast(obj).getBuffer(),
+ KMEnum.cast(obj).length(),
+ KMEnum.cast(obj).getStartOffset(),
+ UINT_TYPE);
}
private void encodeInteger(byte[] val, short len, short startOff, short majorType) {
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java
index 44bf477..7f13853 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java
@@ -73,7 +73,7 @@ public class KMEnum extends KMType {
if (!validateEnum(enumType, NO_VALUE)) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
- short ptr = KMType.instance(ENUM_TYPE, (short) 2);
+ short ptr = KMType.instance(ENUM_TYPE, (short) 2 /* TAG_KEY */);
Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), enumType);
return ptr;
}
@@ -82,12 +82,28 @@ public class KMEnum extends KMType {
if (!validateEnum(enumType, val)) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
- short ptr = KMType.instance(ENUM_TYPE, (short) 3);
+ short ptr = KMType.instance(ENUM_TYPE, (short) (2 /* TAG_KEY */ + 1 /* Byte value */));
Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), enumType);
heap[(short) (ptr + TLV_HEADER_SIZE + 2)] = val;
return ptr;
}
+ public static short instance(short key, byte[] num, short srcOff, short length) {
+ if (length == 1) {
+ return instance(key, num[srcOff]);
+ }
+ if (!validateEnum(key, num, srcOff, length)) {
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ }
+ short ptr = KMType.instance(ENUM_TYPE, (short) (2 /* TAG_KEY */ + KMInteger.UINT_32));
+ Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), key);
+ short destValOff = (short) (ptr + TLV_HEADER_SIZE + 2);
+ Util.arrayFillNonAtomic(heap, destValOff, KMInteger.UINT_32, (byte) 0);
+ Util.arrayCopyNonAtomic(
+ num, srcOff, heap, (short) (destValOff + KMInteger.UINT_32 - length), length);
+ return ptr;
+ }
+
private static void create() {
// The allowed enum values to corresponding enum types in the types array.
if (enums == null) {
@@ -145,13 +161,21 @@ public class KMEnum extends KMType {
}
public short length() {
- return Util.getShort(heap, (short) (KMType.instanceTable[KM_ENUM_OFFSET] + 1));
+ return (short) (Util.getShort(heap, (short) (KMType.instanceTable[KM_ENUM_OFFSET] + 1)) - 2);
}
public byte getVal() {
return heap[(short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)];
}
+ public short value(byte[] dest, short destOff) {
+ return copyToUint32(heap, getStartOffset(), length(), dest, destOff);
+ }
+
+ public short getStartOffset() {
+ return (short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2);
+ }
+
public void setVal(byte val) {
heap[(short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)] = val;
}
@@ -163,4 +187,20 @@ public class KMEnum extends KMType {
public void setEnumType(short type) {
Util.setShort(heap, (short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE), type);
}
+
+ public static boolean validateEnum(short key, byte[] buf, short off, short len) {
+ if (len != KMInteger.UINT_32) {
+ return false;
+ }
+ switch (key) {
+ case KMType.USER_AUTH_TYPE:
+ // HardwareAuthenticatorType::ANY - 0xFFFFFFFF
+ short highShort = Util.getShort(buf, off);
+ short lowShort = Util.getShort(buf, (short) (off + 2));
+ return ((short) 0xFFFF == (short) (highShort & lowShort));
+
+ default:
+ return false;
+ }
+ }
}
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnumTag.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnumTag.java
index a7bcbe6..f4f7e29 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnumTag.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnumTag.java
@@ -73,6 +73,24 @@ public class KMEnumTag extends KMTag {
return ptr;
}
+ public static short instance(short key, byte[] val, short valOff, short valLen) {
+ if (valLen == 1) {
+ return instance(key, val[valOff]);
+ }
+ if (!KMEnum.validateEnum(key, val, valOff, valLen)) {
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ }
+ short ptr =
+ KMType.instance(TAG_TYPE, (short) (2 /* TAG_TYPE */ + 2 /* TAG_KEY */ + KMInteger.UINT_32));
+ Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), ENUM_TAG);
+ Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), key);
+ short destValueOff = (short) (ptr + TLV_HEADER_SIZE + 4);
+ Util.arrayFillNonAtomic(heap, destValueOff, KMInteger.UINT_32, (byte) 0);
+ Util.arrayCopyNonAtomic(
+ val, valOff, heap, (short) (destValueOff + KMInteger.UINT_32 - valLen), valLen);
+ return ptr;
+ }
+
public static KMEnumTag cast(short ptr) {
if (heap[ptr] != TAG_TYPE) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
@@ -137,6 +155,19 @@ public class KMEnumTag extends KMTag {
return KMType.INVALID_VALUE;
}
+ public short length() {
+ return (short)
+ (Util.getShort(heap, (short) (KMType.instanceTable[KM_ENUM_TAG_OFFSET] + 1)) - 4);
+ }
+
+ public short getStartOffset() {
+ return (short) (KMType.instanceTable[KM_ENUM_TAG_OFFSET] + TLV_HEADER_SIZE + 4);
+ }
+
+ public short value(byte[] dest, short destOff) {
+ return copyToUint32(heap, getStartOffset(), length(), dest, destOff);
+ }
+
public short getKey() {
return Util.getShort(
heap, (short) (KMType.instanceTable[KM_ENUM_TAG_OFFSET] + TLV_HEADER_SIZE + 2));
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
index 715a119..a410e00 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
@@ -3001,7 +3001,8 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
if (KMInteger.compare(data[OP_HANDLE], tmpVariables[0]) != 0) {
KMException.throwIt(KMError.KEY_USER_NOT_AUTHENTICATED);
}
- if (!authTokenMatches(op.getUserSecureId(), op.getAuthType(), scratchPad)) {
+ short len = op.getAuthType(scratchPad, (short) 0);
+ if (!authTokenMatches(op.getUserSecureId(), scratchPad, (short) 0, len, scratchPad, len)) {
KMException.throwIt(KMError.KEY_USER_NOT_AUTHENTICATED);
}
}
@@ -3078,10 +3079,10 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
}
// Now check if the device unlock requires password only authentication and whether
// auth token is generated through password authentication or not.
+ scratchPad[0] = KMType.PASSWORD;
+ short authTypeLen = 1;
if (kmDataStore.getDeviceLockPasswordOnly()) {
- ptr = KMHardwareAuthToken.cast(data[HW_TOKEN]).getHwAuthenticatorType();
- ptr = KMEnum.cast(ptr).getVal();
- if (((byte) ptr & KMType.PASSWORD) == 0) {
+ if (!hwAuthTypeMatches(scratchPad, (short) 0, authTypeLen, scratchPad, authTypeLen)) {
KMException.throwIt(KMError.DEVICE_LOCKED);
}
}
@@ -3975,7 +3976,29 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
return false;
}
- private boolean authTokenMatches(short userSecureIdsPtr, short authType, byte[] scratchPad) {
+ public boolean hwAuthTypeMatches(
+ byte[] buf, short off, short len, byte[] scratchPad, short scratchOff) {
+ Util.arrayFillNonAtomic(scratchPad, scratchOff, (short) (2 * KMInteger.UINT_32), (byte) 0);
+ short enumPtr = KMHardwareAuthToken.cast(data[HW_TOKEN]).getHwAuthenticatorType();
+ if (KMInteger.UINT_32 != KMEnum.cast(enumPtr).value(scratchPad, scratchOff)) {
+ return false;
+ }
+ Util.arrayCopyNonAtomic(
+ buf, off, scratchPad, (short) (scratchOff + 2 * KMInteger.UINT_32 - len), len);
+ short highShort = Util.getShort(scratchPad, scratchOff);
+ short lowShort = Util.getShort(scratchPad, (short) (scratchOff + 2));
+ short otherHighShort = Util.getShort(scratchPad, (short) (scratchOff + KMInteger.UINT_32));
+ short otherLowShort = Util.getShort(scratchPad, (short) (scratchOff + KMInteger.UINT_32 + 2));
+ return (0 != (lowShort & otherLowShort) || 0 != (highShort & otherHighShort));
+ }
+
+ private boolean authTokenMatches(
+ short userSecureIdsPtr,
+ byte[] buf,
+ short off,
+ short len,
+ byte[] scratchPad,
+ short scratchOff) {
if (data[HW_TOKEN] == KMType.INVALID_VALUE) {
return false;
}
@@ -3983,12 +4006,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
return false;
}
// check auth type
- tmpVariables[2] = KMHardwareAuthToken.cast(data[HW_TOKEN]).getHwAuthenticatorType();
- tmpVariables[2] = KMEnum.cast(tmpVariables[2]).getVal();
- if (((byte) tmpVariables[2] & (byte) authType) == 0) {
- return false;
- }
- return true;
+ return hwAuthTypeMatches(buf, off, len, scratchPad, scratchOff);
}
private void authorizeUserSecureIdAuthTimeout(KMOperationState op, byte[] scratchPad) {
@@ -4007,16 +4025,19 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
}
// authenticator type must be provided.
if (KMType.INVALID_VALUE
- == (authType = KMEnumTag.getValue(KMType.USER_AUTH_TYPE, data[HW_PARAMETERS]))) {
+ == (authType =
+ KMKeyParameters.findTag(
+ KMType.ENUM_TAG, KMType.USER_AUTH_TYPE, data[HW_PARAMETERS]))) {
// Authentication required, but no auth type found.
KMException.throwIt(KMError.KEY_USER_NOT_AUTHENTICATED);
}
+ short len = KMEnumTag.cast(authType).value(scratchPad, (short) 0);
short authTimeoutTagPtr =
KMKeyParameters.findTag(KMType.UINT_TAG, KMType.AUTH_TIMEOUT, data[HW_PARAMETERS]);
if (authTimeoutTagPtr != KMType.INVALID_VALUE) {
// authenticate user
- if (!authTokenMatches(userSecureIdPtr, authType, scratchPad)) {
+ if (!authTokenMatches(userSecureIdPtr, scratchPad, (short) 0, len, scratchPad, len)) {
KMException.throwIt(KMError.KEY_USER_NOT_AUTHENTICATED);
}
@@ -4041,7 +4062,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
// auth per operation required
// store user secure id and authType in OperationState.
op.setUserSecureId(userSecureIdPtr);
- op.setAuthType((byte) authType);
+ op.setAuthType(scratchPad, (short) 0, len);
// set flags
op.setOneTimeAuthReqd(false);
op.setAuthPerOperationReqd(true);
@@ -4076,7 +4097,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
len += KMInteger.UINT_64;
// concatenate authenticator type - 4 bytes
ptr = KMHardwareAuthToken.cast(hwToken).getHwAuthenticatorType();
- scratchPad[(short) (len + 3)] = KMEnum.cast(ptr).getVal();
+ KMEnum.cast(ptr).value(scratchPad, len);
len += KMInteger.UINT_32;
// concatenate timestamp -8 bytes
ptr = KMHardwareAuthToken.cast(hwToken).getTimestamp();
@@ -4118,7 +4139,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe
len += KMInteger.UINT_64;
// concatenate authenticator type - 4 bytes
ptr = KMHardwareAuthToken.cast(hwToken).getHwAuthenticatorType();
- scratchPad[(short) (len + 3)] = KMEnum.cast(ptr).getVal();
+ KMEnum.cast(ptr).value(scratchPad, len);
len += KMInteger.UINT_32;
// concatenate timestamp - 8 bytes
ptr = KMHardwareAuthToken.cast(hwToken).getTimestamp();
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMOperationState.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMOperationState.java
index 2a53acd..6488577 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMOperationState.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMOperationState.java
@@ -31,7 +31,7 @@ public class KMOperationState {
// sizes
public static final byte OPERATION_HANDLE_SIZE = 8;
- public static final byte DATA_SIZE = 11;
+ public static final byte DATA_SIZE = 12;
public static final byte AUTH_TIME_SIZE = 8;
// Secure user ids 5 * 8 = 40 bytes ( Considering Maximum 5 SECURE USER IDs)
// First two bytes are reserved to store number of secure ids. So total 42 bytes.
@@ -47,7 +47,7 @@ public class KMOperationState {
private static final byte MAC_LENGTH = 7;
private static final byte MGF_DIGEST = 8;
private static final byte AUTH_TYPE = 9;
- private static final byte MIN_MAC_LENGTH = 10;
+ private static final byte MIN_MAC_LENGTH = 11;
private static final byte OPERATION = 0;
private static final byte HMAC_SIGNER_OPERATION = 1;
// Flag masks
@@ -187,12 +187,16 @@ public class KMOperationState {
}
}
- public short getAuthType() {
- return data[AUTH_TYPE];
+ public short getAuthType(byte[] buf, short offset) {
+ Util.arrayFillNonAtomic(buf, offset, (short) 4, (byte) 0);
+ offset = Util.setShort(buf, offset, data[AUTH_TYPE]);
+ Util.setShort(buf, offset, data[AUTH_TYPE + 1]);
+ return (short) 4;
}
- public void setAuthType(byte authType) {
- data[AUTH_TYPE] = authType;
+ public void setAuthType(byte[] buf, short offset, short len) {
+ data[AUTH_TYPE] = Util.getShort(buf, offset);
+ data[(short) (AUTH_TYPE + 1)] = Util.getShort(buf, (short) (offset + 2));
}
public short getUserSecureId() {
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMType.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMType.java
index a18cb7f..fbee00b 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMType.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMType.java
@@ -388,6 +388,21 @@ public abstract class KMType {
return Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE));
}
+ protected static short copyToUint32(
+ byte[] src, short srcOff, short srcLen, byte[] dest, short destOff) {
+ if (srcLen > KMInteger.UINT_32) {
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ }
+ Util.arrayFillNonAtomic(dest, destOff, KMInteger.UINT_32, (byte) 0);
+ Util.arrayCopyNonAtomic(
+ src, srcOff, dest, (short) (destOff + KMInteger.UINT_32 - srcLen), srcLen);
+ return KMInteger.UINT_32;
+ }
+
+ protected byte[] getBuffer() {
+ return heap;
+ }
+
protected static short instance(byte type, short length) {
if (length < 0) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);