aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubrahmanya Manikanta Venkateswarlu Bhamidipati Kameswara Sri <subrahmanyaman@google.com>2023-07-18 03:41:17 +0000
committerSubrahmanya Manikanta Venkateswarlu Bhamidipati Kameswara Sri <subrahmanyaman@google.com>2023-09-11 20:33:22 +0000
commit96396a3b9d25a36c26b64cfccdcb86e6ca10f7ee (patch)
tree19db13f10cae4335fe952d89e87544d629fe18a5
parent49876d0eadd2eee9be91a09bcf7d04e45a95aa4b (diff)
downloadlibese-96396a3b9d25a36c26b64cfccdcb86e6ca10f7ee.tar.gz
Support uint16/uint32 for ENUM Tag.
This commit introduces support for using uint16/uint32 as the underlying data type for an enum tag. Prior to this change, the enum tag was limited to uint8 data type. With this enhancement, uint16 and uint32 can be used, allowing for a wider range of values to be used as enum tags. Bug: 291356939 Test: run vts -m VtsAidlKeyMintTarget Change-Id: I6a6fe9b7023fb8868e0a0f311e3075256532fdb5
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMDecoder.java80
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEncoder.java12
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEnum.java46
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEnumTag.java31
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java53
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMOperationState.java16
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMType.java15
7 files changed, 185 insertions, 68 deletions
diff --git a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMDecoder.java
index dc0101a..6f4e6f4 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMDecoder.java
+++ b/ready_se/google/keymint/KM300/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/KM300/Applet/src/com/android/javacard/keymaster/KMEncoder.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEncoder.java
index 941a0ac..98cad49 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEncoder.java
+++ b/ready_se/google/keymint/KM300/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/KM300/Applet/src/com/android/javacard/keymaster/KMEnum.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEnum.java
index 44bf477..7f13853 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEnum.java
+++ b/ready_se/google/keymint/KM300/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/KM300/Applet/src/com/android/javacard/keymaster/KMEnumTag.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEnumTag.java
index a7bcbe6..f4f7e29 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMEnumTag.java
+++ b/ready_se/google/keymint/KM300/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/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
index 138e505..19c91dd 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
+++ b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
@@ -3010,7 +3010,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);
}
}
@@ -3087,10 +3088,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);
}
}
@@ -3976,7 +3977,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;
}
@@ -3984,12 +4007,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) {
@@ -4008,16 +4026,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);
}
@@ -4042,7 +4063,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);
@@ -4077,7 +4098,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();
@@ -4119,7 +4140,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/KM300/Applet/src/com/android/javacard/keymaster/KMOperationState.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMOperationState.java
index 2a53acd..6488577 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMOperationState.java
+++ b/ready_se/google/keymint/KM300/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/KM300/Applet/src/com/android/javacard/keymaster/KMType.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMType.java
index dc89604..59f45da 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMType.java
+++ b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMType.java
@@ -390,6 +390,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);