From f80a3b7c33f18286bd9ea72aff3575ff66ddc461 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 21 Mar 2021 20:32:45 +0000 Subject: [PATCH 01/16] Performance fix: Reduced NVM writes --- .../android/javacard/keymaster/KMArray.java | 16 +-- .../android/javacard/keymaster/KMBoolTag.java | 10 +- .../javacard/keymaster/KMByteBlob.java | 18 ++-- .../android/javacard/keymaster/KMByteTag.java | 12 ++- .../android/javacard/keymaster/KMDecoder.java | 93 ++++++++++------ .../android/javacard/keymaster/KMEncoder.java | 100 ++++++++++-------- .../android/javacard/keymaster/KMEnum.java | 16 +-- .../javacard/keymaster/KMEnumArrayTag.java | 14 +-- .../android/javacard/keymaster/KMEnumTag.java | 10 +- .../javacard/keymaster/KMException.java | 16 ++- .../keymaster/KMHardwareAuthToken.java | 8 +- .../keymaster/KMHmacSharingParameters.java | 8 +- .../android/javacard/keymaster/KMInteger.java | 22 ++-- .../javacard/keymaster/KMIntegerArrayTag.java | 12 ++- .../javacard/keymaster/KMIntegerTag.java | 14 +-- .../keymaster/KMKeyCharacteristics.java | 8 +- .../javacard/keymaster/KMKeyParameters.java | 8 +- .../javacard/keymaster/KMKeymasterApplet.java | 3 +- .../javacard/keymaster/KMOperationState.java | 52 +++++---- .../javacard/keymaster/KMRepository.java | 56 +++++----- .../keymaster/KMVerificationToken.java | 8 +- 21 files changed, 295 insertions(+), 209 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMArray.java b/Applet/src/com/android/javacard/keymaster/KMArray.java index f2206474..a2de179d 100644 --- a/Applet/src/com/android/javacard/keymaster/KMArray.java +++ b/Applet/src/com/android/javacard/keymaster/KMArray.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -36,16 +37,17 @@ public class KMArray extends KMType { public static final short ANY_ARRAY_LENGTH = 0x1000; private static final short ARRAY_HEADER_SIZE = 4; private static KMArray prototype; - private static short instPtr; + private short[] instPtr; private KMArray() { + instPtr = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMArray proto(short ptr) { if (prototype == null) { prototype = new KMArray(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -90,7 +92,7 @@ public void add(short index, short objPtr) { } Util.setShort( heap, - (short) (instPtr + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2)), + (short) (instPtr[0] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2)), objPtr); } @@ -100,19 +102,19 @@ public short get(short index) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } return Util.getShort( - heap, (short) (instPtr + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2))); + heap, (short) (instPtr[0] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2))); } public short containedType() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short getStartOff() { - return (short) (instPtr + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE); + return (short) (instPtr[0] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE); } public short length() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public byte[] getBuffer() { diff --git a/Applet/src/com/android/javacard/keymaster/KMBoolTag.java b/Applet/src/com/android/javacard/keymaster/KMBoolTag.java index 173e6269..f0b642c7 100644 --- a/Applet/src/com/android/javacard/keymaster/KMBoolTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMBoolTag.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -30,7 +31,7 @@ public class KMBoolTag extends KMTag { private static KMBoolTag prototype; - private static short instPtr; + private short[] instPtr; // The allowed tag keys of type bool tag. private static final short[] tags = { @@ -49,13 +50,14 @@ public class KMBoolTag extends KMTag { }; private KMBoolTag() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMBoolTag proto(short ptr) { if (prototype == null) { prototype = new KMBoolTag(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -89,7 +91,7 @@ public static KMBoolTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -97,7 +99,7 @@ public short getTagType() { } public byte getVal() { - return heap[(short) (instPtr + TLV_HEADER_SIZE + 4)]; + return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 4)]; } // validate the tag key. diff --git a/Applet/src/com/android/javacard/keymaster/KMByteBlob.java b/Applet/src/com/android/javacard/keymaster/KMByteBlob.java index 001bab01..2c91ac6b 100644 --- a/Applet/src/com/android/javacard/keymaster/KMByteBlob.java +++ b/Applet/src/com/android/javacard/keymaster/KMByteBlob.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -28,16 +29,17 @@ public class KMByteBlob extends KMType { private static KMByteBlob prototype; - private static short instPtr; + private short[] instPtr; private KMByteBlob() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMByteBlob proto(short ptr) { if (prototype == null) { prototype = new KMByteBlob(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -75,7 +77,7 @@ public void add(short index, byte val) { if (index >= len) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } - heap[(short) (instPtr + TLV_HEADER_SIZE + index)] = val; + heap[(short) (instPtr[0] + TLV_HEADER_SIZE + index)] = val; } // Get the byte @@ -84,17 +86,17 @@ public byte get(short index) { if (index >= len) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } - return heap[(short) (instPtr + TLV_HEADER_SIZE + index)]; + return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + index)]; } // Get the start of blob public short getStartOff() { - return (short) (instPtr + TLV_HEADER_SIZE); + return (short) (instPtr[0] + TLV_HEADER_SIZE); } // Get the length of the blob public short length() { - return Util.getShort(heap, (short) (instPtr + 1)); + return Util.getShort(heap, (short) (instPtr[0] + 1)); } // Get the buffer pointer in which blob is contained. @@ -127,8 +129,8 @@ public boolean isValid() { } public void decrementLength(short len) { - short length = Util.getShort(heap, (short) (instPtr + 1)); + short length = Util.getShort(heap, (short) (instPtr[0] + 1)); length = (short) (length - len); - Util.setShort(heap, (short) (instPtr + 1), length); + Util.setShort(heap, (short) (instPtr[0] + 1), length); } } diff --git a/Applet/src/com/android/javacard/keymaster/KMByteTag.java b/Applet/src/com/android/javacard/keymaster/KMByteTag.java index 4384891d..0ae6f881 100644 --- a/Applet/src/com/android/javacard/keymaster/KMByteTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMByteTag.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -29,7 +30,7 @@ public class KMByteTag extends KMTag { private static KMByteTag prototype; - private static short instPtr; + private short[] instPtr; // The allowed tag keys of type bool tag private static final short[] tags = { @@ -55,13 +56,14 @@ public class KMByteTag extends KMTag { }; private KMByteTag() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMByteTag proto(short ptr) { if (prototype == null) { prototype = new KMByteTag(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -107,7 +109,7 @@ public static KMByteTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -115,11 +117,11 @@ public short getTagType() { } public short getValue() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); } public short length() { - short blobPtr = Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 4)); + short blobPtr = Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); return KMByteBlob.cast(blobPtr).length(); } diff --git a/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/Applet/src/com/android/javacard/keymaster/KMDecoder.java index 520ffb7c..c2579372 100644 --- a/Applet/src/com/android/javacard/keymaster/KMDecoder.java +++ b/Applet/src/com/android/javacard/keymaster/KMDecoder.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; public class KMDecoder { @@ -38,29 +39,33 @@ public class KMDecoder { private static final short UINT32_LENGTH = 0x1A; private static final short UINT64_LENGTH = 0x1B; - private byte[] buffer; - private short startOff; - private short length; - private short tagType; - private short tagKey; + private static final short SCRATCH_BUF_SIZE = 6; + private static final short START_OFFSET = 0; + private static final short LEN_OFFSET = 2; + private static final short TAG_KEY_OFFSET = 4; + private Object[] bufferRef; + private short[] scratchBuf; public KMDecoder() { - buffer = null; - startOff = 0; - length = 0; + bufferRef = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET); + scratchBuf = (short[]) JCSystem.makeTransientShortArray(SCRATCH_BUF_SIZE, JCSystem.CLEAR_ON_RESET); + bufferRef[0] = null; + scratchBuf[START_OFFSET] = (short) 0; + scratchBuf[LEN_OFFSET] = (short) 0; + scratchBuf[TAG_KEY_OFFSET] = (short) 0; } public short decode(short expression, byte[] buffer, short startOff, short length) { - this.buffer = buffer; - this.startOff = startOff; - this.length = (short) (startOff + length); + bufferRef[0] = buffer; + scratchBuf[START_OFFSET] = startOff; + scratchBuf[LEN_OFFSET] = (short) (startOff + length); return decode(expression); } public short decodeArray(short exp, byte[] buffer, short startOff, short length) { - this.buffer = buffer; - this.startOff = startOff; - this.length = (short) (startOff + length); + bufferRef[0] = buffer; + scratchBuf[START_OFFSET] = startOff; + scratchBuf[LEN_OFFSET] = (short) (startOff + length); short payloadLength = readMajorTypeWithPayloadLength(ARRAY_TYPE); short expLength = KMArray.cast(exp).length(); if (payloadLength > expLength) { @@ -139,7 +144,7 @@ private short decodeVerificationToken(short exp) { private short decodeHwAuthToken(short exp) { short vals = decode(KMHardwareAuthToken.cast(exp).getVals()); - return KMHardwareAuthToken.cast(exp).instance(vals); + return KMHardwareAuthToken.instance(vals); } private short decodeHmacSharingParam(short exp) { @@ -195,32 +200,32 @@ private short decodeKeyParam(short exp) { private short decodeEnumArrayTag(short exp) { readTagKey(KMEnumArrayTag.cast(exp).getTagType()); - return KMEnumArrayTag.instance(this.tagKey, decode(KMEnumArrayTag.cast(exp).getValues())); + return KMEnumArrayTag.instance(scratchBuf[TAG_KEY_OFFSET], decode(KMEnumArrayTag.cast(exp).getValues())); } private short decodeIntegerArrayTag(short exp) { readTagKey(KMIntegerArrayTag.cast(exp).getTagType()); // the values are array of integers. return KMIntegerArrayTag.instance(KMIntegerArrayTag.cast(exp).getTagType(), - this.tagKey, decode(KMIntegerArrayTag.cast(exp).getValues())); + scratchBuf[TAG_KEY_OFFSET], decode(KMIntegerArrayTag.cast(exp).getValues())); } private short decodeIntegerTag(short exp) { readTagKey(KMIntegerTag.cast(exp).getTagType()); // the value is an integer return KMIntegerTag.instance(KMIntegerTag.cast(exp).getTagType(), - this.tagKey, decode(KMIntegerTag.cast(exp).getValue())); + scratchBuf[TAG_KEY_OFFSET], decode(KMIntegerTag.cast(exp).getValue())); } private short decodeBytesTag(short exp) { readTagKey(KMByteTag.cast(exp).getTagType()); // The value must be byte blob - return KMByteTag.instance(this.tagKey, decode(KMByteTag.cast(exp).getValue())); + return KMByteTag.instance(scratchBuf[TAG_KEY_OFFSET], decode(KMByteTag.cast(exp).getValue())); } private short decodeArray(short exp) { short payloadLength = readMajorTypeWithPayloadLength(ARRAY_TYPE); - short arrPtr = KMArray.cast(exp).instance(payloadLength); + short arrPtr = KMArray.instance(payloadLength); short index = 0; short type; short obj; @@ -250,6 +255,8 @@ private short decodeArray(short exp) { private short decodeEnumTag(short exp) { readTagKey(KMEnumTag.cast(exp).getTagType()); + 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) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); @@ -264,14 +271,19 @@ private short decodeEnumTag(short exp) { 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]; incrementStartOff((short) 1); } - return KMEnumTag.instance(tagKey, enumVal); + return KMEnumTag.instance(scratchBuf[TAG_KEY_OFFSET], enumVal); } private short decodeBoolTag(short exp) { readTagKey(KMBoolTag.cast(exp).getTagType()); + byte[] buffer = (byte[])bufferRef[0]; + short startOff = scratchBuf[START_OFFSET]; // BOOL Tag is a leaf node and it must always have tiny encoded uint value = 1. if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); @@ -280,10 +292,12 @@ private short decodeBoolTag(short exp) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } incrementStartOff((short) 1); - return KMBoolTag.instance(tagKey); + return KMBoolTag.instance(scratchBuf[TAG_KEY_OFFSET]); } 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); @@ -298,6 +312,9 @@ private short decodeEnum(short exp) { 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); } @@ -306,6 +323,8 @@ private short decodeEnum(short exp) { private short decodeInteger(short exp) { short inst; + short startOff = scratchBuf[START_OFFSET]; + byte[] buffer = (byte[])bufferRef[0]; if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } @@ -314,6 +333,9 @@ private short decodeInteger(short exp) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } incrementStartOff((short) 1); + // startOff is incremented so update the startOff + // with latest value before using it. + startOff = scratchBuf[START_OFFSET]; if (len < UINT8_LENGTH) { inst = KMInteger.uint_8((byte) (len & ADDITIONAL_MASK)); } else if (len == UINT8_LENGTH) { @@ -334,12 +356,14 @@ private short decodeInteger(short exp) { private short decodeByteBlob(short exp) { short payloadLength = readMajorTypeWithPayloadLength(BYTES_TYPE); - short inst = KMByteBlob.instance(buffer, startOff, payloadLength); + short inst = KMByteBlob.instance((byte[])bufferRef[0], scratchBuf[START_OFFSET], payloadLength); incrementStartOff(payloadLength); return inst; } private short peekTagType() { + byte[] buffer = (byte[])bufferRef[0]; + short startOff = scratchBuf[START_OFFSET]; if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } @@ -353,6 +377,8 @@ private short peekTagType() { } private void readTagKey(short expectedTagType) { + byte[] buffer = (byte[])bufferRef[0]; + short startOff = scratchBuf[START_OFFSET]; if ((buffer[startOff] & MAJOR_TYPE_MASK) != UINT_TYPE) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } @@ -360,8 +386,8 @@ private void readTagKey(short expectedTagType) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } incrementStartOff((short) 1); - this.tagType = readShort(); - this.tagKey = readShort(); + short tagType = readShort(); + scratchBuf[TAG_KEY_OFFSET] = readShort(); if (tagType != expectedTagType) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } @@ -389,31 +415,34 @@ private short readMajorTypeWithPayloadLength(short majorType) { } private short readShort() { + byte[] buffer = (byte[])bufferRef[0]; + short startOff = scratchBuf[START_OFFSET]; short val = Util.makeShort(buffer[startOff], buffer[(short) (startOff + 1)]); incrementStartOff((short) 2); return val; } private byte readByte() { - byte val = buffer[startOff]; + short startOff = scratchBuf[START_OFFSET]; + byte val = ((byte[])bufferRef[0])[startOff]; incrementStartOff((short) 1); return val; } private void incrementStartOff(short inc) { - startOff += inc; - if (startOff > this.length) { + scratchBuf[START_OFFSET] += inc; + if (scratchBuf[START_OFFSET] > scratchBuf[LEN_OFFSET]) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } } public short readCertificateChainLengthAndHeaderLen(byte[] buf, short bufOffset, short bufLen) { - this.buffer = buf; - this.startOff = bufOffset; - this.length = (short) (bufOffset + bufLen); + bufferRef[0] = buf; + scratchBuf[START_OFFSET] = bufOffset; + scratchBuf[LEN_OFFSET] = (short) (bufOffset + bufLen); short totalLen = readMajorTypeWithPayloadLength(BYTES_TYPE); - totalLen += (short) (startOff - bufOffset); + totalLen += (short) (scratchBuf[START_OFFSET] - bufOffset); return totalLen; } } diff --git a/Applet/src/com/android/javacard/keymaster/KMEncoder.java b/Applet/src/com/android/javacard/keymaster/KMEncoder.java index 61163c00..47e6d305 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEncoder.java +++ b/Applet/src/com/android/javacard/keymaster/KMEncoder.java @@ -39,27 +39,34 @@ public class KMEncoder { private static final byte UINT64_LENGTH = (byte) 0x1B; private static final short TINY_PAYLOAD = 0x17; private static final short SHORT_PAYLOAD = 0x100; - private byte[] buffer; - private short startOff; - private short length; - private static short[] stack; - private static byte stackPtr; + private static final short STACK_SIZE = (short) 50; + private static final short SCRATCH_BUF_SIZE = (short) 6; + private static final short START_OFFSET = (short) 0; + private static final short LEN_OFFSET = (short) 2; + private static final short STACK_PTR_OFFSET = (short) 4; + + private Object[] bufferRef; + private short[] scratchBuf; + private short[] stack; public KMEncoder() { - buffer = null; - startOff = 0; - length = 0; - stack = JCSystem.makeTransientShortArray((short) 50, JCSystem.CLEAR_ON_RESET); + bufferRef = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET); + scratchBuf = JCSystem.makeTransientShortArray((short) SCRATCH_BUF_SIZE, JCSystem.CLEAR_ON_RESET); + stack = JCSystem.makeTransientShortArray(STACK_SIZE, JCSystem.CLEAR_ON_RESET); + bufferRef[0] = null; + scratchBuf[START_OFFSET] = (short) 0; + scratchBuf[LEN_OFFSET] = (short) 0; + scratchBuf[STACK_PTR_OFFSET] = (short) 0; } - private static void push(short objPtr) { - stack[stackPtr] = objPtr; - stackPtr++; + private void push(short objPtr) { + stack[scratchBuf[STACK_PTR_OFFSET]] = objPtr; + scratchBuf[STACK_PTR_OFFSET]++; } - private static short pop() { - stackPtr--; - return stack[stackPtr]; + private short pop() { + scratchBuf[STACK_PTR_OFFSET]--; + return stack[scratchBuf[STACK_PTR_OFFSET]]; } private void encode(short obj) { @@ -67,26 +74,26 @@ private void encode(short obj) { } public short encode(short object, byte[] buffer, short startOff) { - stackPtr = 0; - this.buffer = buffer; - this.startOff = startOff; + scratchBuf[STACK_PTR_OFFSET] = 0; + bufferRef[0] = buffer; + scratchBuf[START_OFFSET] = startOff; short len = (short) buffer.length; if ((len < 0) || (len > KMKeymasterApplet.MAX_LENGTH)) { - this.length = KMKeymasterApplet.MAX_LENGTH; + scratchBuf[LEN_OFFSET] = KMKeymasterApplet.MAX_LENGTH; } else { - this.length = (short) buffer.length; + scratchBuf[LEN_OFFSET] = (short) buffer.length; } //this.length = (short)(startOff + length); push(object); encode(); - return (short) (this.startOff - startOff); + return (short) (scratchBuf[START_OFFSET] - startOff); } // array{KMError.OK,Array{KMByteBlobs}} public void encodeCertChain(byte[] buffer, short offset, short length) { - this.buffer = buffer; - this.startOff = offset; - this.length = (short) (offset + 3); + bufferRef[0] = buffer; + scratchBuf[START_OFFSET] = offset; + scratchBuf[LEN_OFFSET] = (short) (offset + 3); writeMajorTypeWithLength(ARRAY_TYPE, (short) 2); // Array of 2 elements writeByte(UINT_TYPE); // Error.OK @@ -94,22 +101,22 @@ public void encodeCertChain(byte[] buffer, short offset, short length) { //array{KMError.OK,Array{KMByteBlobs}} public short encodeCert(byte[] certBuffer, short bufferStart, short certStart, short certLength) { - this.buffer = certBuffer; - this.startOff = certStart; - this.length = (short) (certStart + 1); + bufferRef[0] = certBuffer; + scratchBuf[START_OFFSET] = certStart; + scratchBuf[LEN_OFFSET] = (short) (certStart + 1); //Array header - 2 elements i.e. 1 byte - this.startOff--; + scratchBuf[START_OFFSET]--; // Error.Ok - 1 byte - this.startOff--; + scratchBuf[START_OFFSET]--; //Array header - 2 elements i.e. 1 byte - this.startOff--; + scratchBuf[START_OFFSET]--; // Cert Byte blob - typically 2 bytes length i.e. 3 bytes header - this.startOff -= 2; + scratchBuf[START_OFFSET] -= 2; if (certLength >= SHORT_PAYLOAD) { - this.startOff--; + scratchBuf[START_OFFSET]--; } - bufferStart = startOff; - if (this.startOff < bufferStart) { + bufferStart = scratchBuf[START_OFFSET]; + if (scratchBuf[START_OFFSET] < bufferStart) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } writeMajorTypeWithLength(ARRAY_TYPE, (short) 2); // Array of 2 elements @@ -120,9 +127,9 @@ public short encodeCert(byte[] certBuffer, short bufferStart, short certStart, s } public short encodeError(short err, byte[] buffer, short startOff, short length) { - this.buffer = buffer; - this.startOff = startOff; - this.length = (short) (startOff + length); + bufferRef[0] = buffer; + scratchBuf[START_OFFSET] = startOff; + scratchBuf[LEN_OFFSET] = (short) (startOff + length); // encode the err as UINT with value in err - should not be greater then 5 bytes. if (err < UINT8_LENGTH) { writeByte((byte) (UINT_TYPE | err)); @@ -133,11 +140,11 @@ public short encodeError(short err, byte[] buffer, short startOff, short length) writeByte((byte) (UINT_TYPE | UINT16_LENGTH)); writeShort(err); } - return (short) (this.startOff - startOff); + return (short) (scratchBuf[START_OFFSET] - startOff); } private void encode() { - while (stackPtr > 0) { + while (scratchBuf[STACK_PTR_OFFSET] > 0) { short exp = pop(); byte type = KMType.getType(exp); switch (type) { @@ -352,25 +359,28 @@ private void writeMajorTypeWithLength(byte majorType, short len) { } private void writeBytes(byte[] buf, short start, short len) { - Util.arrayCopyNonAtomic(buf, start, buffer, startOff, len); + byte[] buffer = (byte[]) bufferRef[0]; + Util.arrayCopyNonAtomic(buf, start, buffer, scratchBuf[START_OFFSET], len); incrementStartOff(len); } private void writeShort(short val) { - buffer[startOff] = (byte) ((val >> 8) & 0xFF); + byte[] buffer = (byte[]) bufferRef[0]; + buffer[scratchBuf[START_OFFSET]] = (byte) ((val >> 8) & 0xFF); incrementStartOff((short) 1); - buffer[startOff] = (byte) ((val & 0xFF)); + buffer[scratchBuf[START_OFFSET]] = (byte) ((val & 0xFF)); incrementStartOff((short) 1); } private void writeByte(byte val) { - buffer[startOff] = val; + byte[] buffer = (byte[]) bufferRef[0]; + buffer[scratchBuf[START_OFFSET]] = val; incrementStartOff((short) 1); } private void incrementStartOff(short inc) { - startOff += inc; - if (startOff >= this.length) { + scratchBuf[START_OFFSET] += inc; + if (scratchBuf[START_OFFSET] >= scratchBuf[LEN_OFFSET]) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); } } diff --git a/Applet/src/com/android/javacard/keymaster/KMEnum.java b/Applet/src/com/android/javacard/keymaster/KMEnum.java index 6dbdf7ce..3c5e753f 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnum.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnum.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -28,7 +29,7 @@ public class KMEnum extends KMType { private static KMEnum prototype; - private static short instPtr; + private short[] instPtr; // The allowed enum types. private static short[] types = { @@ -45,13 +46,14 @@ public class KMEnum extends KMType { private static Object[] enums = null; private KMEnum() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMEnum proto(short ptr) { if (prototype == null) { prototype = new KMEnum(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -61,7 +63,7 @@ public static short exp() { } public short length() { - return Util.getShort(heap, (short) (instPtr + 1)); + return Util.getShort(heap, (short) (instPtr[0] + 1)); } public static KMEnum cast(short ptr) { @@ -118,19 +120,19 @@ private static void create() { } public void setVal(byte val) { - heap[(short) (instPtr + TLV_HEADER_SIZE + 2)] = val; + heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 2)] = val; } public byte getVal() { - return heap[(short) (instPtr + TLV_HEADER_SIZE + 2)]; + return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 2)]; } public void setEnumType(short type) { - Util.setShort(heap, (short) (instPtr + TLV_HEADER_SIZE), type); + Util.setShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE), type); } public short getEnumType() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } // isValidTag enumeration keys and values. diff --git a/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java index 1cc5730d..43578509 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -27,22 +28,23 @@ public class KMEnumArrayTag extends KMTag { private static KMEnumArrayTag prototype; - private static short instPtr; + private short[] instPtr; // The allowed tag keys of enum array type. - private static short[] tags = {PURPOSE, BLOCK_MODE, DIGEST, PADDING}; + private static final short[] tags = {PURPOSE, BLOCK_MODE, DIGEST, PADDING}; // Tag Values. private static Object[] enums = null; private KMEnumArrayTag() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMEnumArrayTag proto(short ptr) { if (prototype == null) { prototype = new KMEnumArrayTag(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -107,7 +109,7 @@ public static KMEnumArrayTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -115,11 +117,11 @@ public short getTagType() { } public short getValues() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); } public short length() { - short blobPtr = Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 4)); + short blobPtr = Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); return KMByteBlob.cast(blobPtr).length(); } diff --git a/Applet/src/com/android/javacard/keymaster/KMEnumTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumTag.java index 485572ed..a8ff3f36 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnumTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnumTag.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -28,7 +29,7 @@ public class KMEnumTag extends KMTag { private static KMEnumTag prototype; - private static short instPtr; + private short[] instPtr; // The allowed tag keys of type enum tag. @@ -39,13 +40,14 @@ public class KMEnumTag extends KMTag { private static Object[] enums = null; private KMEnumTag() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMEnumTag proto(short ptr) { if (prototype == null) { prototype = new KMEnumTag(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -88,7 +90,7 @@ public static KMEnumTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -96,7 +98,7 @@ public short getTagType() { } public byte getValue() { - return heap[(short) (instPtr + TLV_HEADER_SIZE + 4)]; + return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 4)]; } public static void create() { diff --git a/Applet/src/com/android/javacard/keymaster/KMException.java b/Applet/src/com/android/javacard/keymaster/KMException.java index 0f4f6740..bf588aba 100644 --- a/Applet/src/com/android/javacard/keymaster/KMException.java +++ b/Applet/src/com/android/javacard/keymaster/KMException.java @@ -16,21 +16,25 @@ package com.android.javacard.keymaster; +import javacard.framework.JCSystem; + /** * KMException is shared instance of exception used for all exceptions in the applet. It is used to * throw EMError errors. */ public class KMException extends RuntimeException { - public static short reason; + public short[] reason; public static KMException exception; private KMException() { + reason = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } public static void throwIt(short reason) { - KMException.reason = reason; - throw instance(); + instance(); + exception.reason[(short) 0] = reason; + throw exception; } public static KMException instance() { @@ -41,7 +45,11 @@ public static KMException instance() { } public void clear() { - reason = KMError.UNKNOWN_ERROR; + exception.reason[(short) 0] = KMError.UNKNOWN_ERROR; + } + + public static short getReason() { + return exception.reason[0]; } } diff --git a/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java b/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java index 71e2e8bb..8a68be77 100644 --- a/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java +++ b/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -37,9 +38,10 @@ public class KMHardwareAuthToken extends KMType { public static final byte MAC = 0x05; private static KMHardwareAuthToken prototype; - private static short instPtr; + private short[] instPtr; private KMHardwareAuthToken() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } public static short exp() { @@ -58,7 +60,7 @@ private static KMHardwareAuthToken proto(short ptr) { if (prototype == null) { prototype = new KMHardwareAuthToken(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -96,7 +98,7 @@ public static KMHardwareAuthToken cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java b/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java index 81a19bd3..b149b8bd 100644 --- a/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java +++ b/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -32,9 +33,10 @@ public class KMHmacSharingParameters extends KMType { public static final byte NONCE = 0x01; private static KMHmacSharingParameters prototype; - private static short instPtr; + private short[] instPtr; private KMHmacSharingParameters() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } public static short exp() { @@ -49,7 +51,7 @@ private static KMHmacSharingParameters proto(short ptr) { if (prototype == null) { prototype = new KMHmacSharingParameters(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -79,7 +81,7 @@ public static KMHmacSharingParameters cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMInteger.java b/Applet/src/com/android/javacard/keymaster/KMInteger.java index 1330f85f..997eb637 100644 --- a/Applet/src/com/android/javacard/keymaster/KMInteger.java +++ b/Applet/src/com/android/javacard/keymaster/KMInteger.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -29,16 +30,17 @@ public class KMInteger extends KMType { public static final short UINT_32 = 4; public static final short UINT_64 = 8; private static KMInteger prototype; - private static short instPtr; + private short[] instPtr; private KMInteger() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMInteger proto(short ptr) { if (prototype == null) { prototype = new KMInteger(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -115,7 +117,7 @@ public static short uint_64(byte[] num, short offset) { // Get the length of the integer public short length() { - return Util.getShort(heap, (short) (instPtr + 1)); + return Util.getShort(heap, (short) (instPtr[0] + 1)); } // Get the buffer pointer in which blob is contained. @@ -125,7 +127,7 @@ public byte[] getBuffer() { // Get the start of value public short getStartOff() { - return (short) (instPtr + TLV_HEADER_SIZE); + return (short) (instPtr[0] + TLV_HEADER_SIZE); } public void getValue(byte[] dest, short destOff, short length) { @@ -136,28 +138,28 @@ public void getValue(byte[] dest, short destOff, short length) { length = length(); destOff += length; } - Util.arrayCopyNonAtomic(heap, (short) (instPtr + TLV_HEADER_SIZE), dest, destOff, length); + Util.arrayCopyNonAtomic(heap, (short) (instPtr[0] + TLV_HEADER_SIZE), dest, destOff, length); } public void setValue(byte[] src, short srcOff) { - Util.arrayCopyNonAtomic(src, srcOff, heap, (short) (instPtr + TLV_HEADER_SIZE), length()); + Util.arrayCopyNonAtomic(src, srcOff, heap, (short) (instPtr[0] + TLV_HEADER_SIZE), length()); } public short value(byte[] dest, short destOff) { - Util.arrayCopyNonAtomic(heap, (short) (instPtr + TLV_HEADER_SIZE), dest, destOff, length()); + Util.arrayCopyNonAtomic(heap, (short) (instPtr[0] + TLV_HEADER_SIZE), dest, destOff, length()); return length(); } public short getShort() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public short getSignificantShort() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public byte getByte() { - return heap[(short) (instPtr + TLV_HEADER_SIZE + 3)]; + return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 3)]; } public boolean isZero() { diff --git a/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java index b97f5fa6..b9e3b3af 100644 --- a/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -28,18 +29,19 @@ public class KMIntegerArrayTag extends KMTag { private static KMIntegerArrayTag prototype; - private static short instPtr; + private short[] instPtr; private static final short[] tags = {USER_SECURE_ID}; private KMIntegerArrayTag() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMIntegerArrayTag proto(short ptr) { if (prototype == null) { prototype = new KMIntegerArrayTag(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -95,15 +97,15 @@ public static KMIntegerArrayTag cast(short ptr) { } public short getTagType() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short getKey() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public short getValues() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java index 44136ec4..5c79635f 100644 --- a/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -28,7 +29,7 @@ public class KMIntegerTag extends KMTag { private static KMIntegerTag prototype; - private static short instPtr; + private short[] instPtr; // Allowed tag keys. private static final short[] tags = { // UINT @@ -53,13 +54,14 @@ public class KMIntegerTag extends KMTag { }; private KMIntegerTag() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMIntegerTag proto(short ptr) { if (prototype == null) { prototype = new KMIntegerTag(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -115,15 +117,15 @@ public static KMIntegerTag cast(short ptr) { } public short getTagType() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short getKey() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); } public short getValue() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); } public short length() { @@ -173,7 +175,7 @@ public static short getValue( } public boolean isValidKeySize(byte alg) { - short val = KMIntegerTag.cast(instPtr).getValue(); + short val = KMIntegerTag.cast(instPtr[0]).getValue(); if (KMInteger.cast(val).getSignificantShort() != 0) { return false; } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java b/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java index 2ad16117..5ac2ef4d 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -31,9 +32,10 @@ public class KMKeyCharacteristics extends KMType { public static final byte SOFTWARE_ENFORCED = 0x00; public static final byte HARDWARE_ENFORCED = 0x01; private static KMKeyCharacteristics prototype; - private static short instPtr; + private short[] instPtr; private KMKeyCharacteristics() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } public static short exp() { @@ -50,7 +52,7 @@ private static KMKeyCharacteristics proto(short ptr) { if (prototype == null) { prototype = new KMKeyCharacteristics(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -80,7 +82,7 @@ public static KMKeyCharacteristics cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java index cfdd9c30..3c53bb35 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -28,16 +29,17 @@ public class KMKeyParameters extends KMType { private static KMKeyParameters prototype; - private static short instPtr; + private short[] instPtr; private KMKeyParameters() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMKeyParameters proto(short ptr) { if (prototype == null) { prototype = new KMKeyParameters(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -74,7 +76,7 @@ public static KMKeyParameters cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index e8c1a8cc..59af95b6 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -192,7 +192,6 @@ protected KMKeymasterApplet(KMSEProvider seImpl) { seProvider = seImpl; boolean isUpgrading = seImpl.isUpgrading(); repository = new KMRepository(isUpgrading); - byte[] buf = JCSystem.makeTransientByteArray((short) 32, JCSystem.CLEAR_ON_DESELECT); data = JCSystem.makeTransientShortArray((short) DATA_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); tmpVariables = JCSystem.makeTransientShortArray((short) TMP_VARIABLE_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); @@ -466,7 +465,7 @@ && isProvisioningComplete())) { } } catch (KMException exception) { freeOperations(); - sendError(apdu, KMException.reason); + sendError(apdu, KMException.getReason()); exception.clear(); } catch (ISOException exp) { sendError(apdu, mapISOErrorToKMError(exp.getReason())); diff --git a/Applet/src/com/android/javacard/keymaster/KMOperationState.java b/Applet/src/com/android/javacard/keymaster/KMOperationState.java index f1c65ea4..333962aa 100644 --- a/Applet/src/com/android/javacard/keymaster/KMOperationState.java +++ b/Applet/src/com/android/javacard/keymaster/KMOperationState.java @@ -31,6 +31,8 @@ public class KMOperationState { public static final byte MAX_REFS = 1; private static final byte DATA = 0; private static final byte REFS = 1; + private static final byte KMOPERATION = 0; + private static final byte SLOT = 1; // byte type private static final byte ALG = 0; private static final byte PURPOSE = 1; @@ -53,14 +55,15 @@ public class KMOperationState { // Object References private static final byte OPERATION = 0; - private static KMOperation op; - private static byte[] data; - private static Object[] slot; + private byte[] data; + private Object[] objRefs; private static KMOperationState prototype; - private static boolean dFlag; + private byte[] dFlag; private KMOperationState() { data = JCSystem.makeTransientByteArray(MAX_DATA, JCSystem.CLEAR_ON_RESET); + objRefs = JCSystem.makeTransientObjectArray((short) 2, JCSystem.CLEAR_ON_RESET); + dFlag = JCSystem.makeTransientByteArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMOperationState proto() { @@ -73,28 +76,30 @@ private static KMOperationState proto() { public static KMOperationState instance(short opHandle, Object[] slot) { KMOperationState opState = proto(); opState.reset(); - Util.setShort(data, OP_HANDLE, opHandle); - KMOperationState.slot = slot; + Util.setShort(prototype.data, OP_HANDLE, opHandle); + prototype.objRefs[SLOT] = slot; return opState; } public static KMOperationState read(byte[] oprHandle, short off, Object[] slot) { KMOperationState opState = proto(); opState.reset(); - Util.arrayCopy((byte[]) slot[DATA], (short) 0, data, (short) 0, (short) data.length); + Util.arrayCopy((byte[]) slot[DATA], (short) 0, prototype.data, (short) 0, (short) prototype.data.length); Object[] ops = ((Object[]) slot[REFS]); - op = (KMOperation) ops[OPERATION]; - Util.setShort(data, OP_HANDLE, KMInteger.uint_64(oprHandle, off)); - KMOperationState.slot = slot; + prototype.objRefs[KMOPERATION] = ops[OPERATION]; + Util.setShort(prototype.data, OP_HANDLE, KMInteger.uint_64(oprHandle, off)); + prototype.objRefs[SLOT] = slot; return opState; } public void persist() { - if (!dFlag) { + if (0 == dFlag[0]) { return; } - KMRepository.instance().persistOperation(data, Util.getShort(data, OP_HANDLE), op); - dFlag = false; + KMRepository.instance().persistOperation(data, + Util.getShort(data, OP_HANDLE), + (KMOperation) objRefs[KMOPERATION]); + dFlag[0] = 0; } public void setKeySize(short keySize) { @@ -106,30 +111,31 @@ public short getKeySize() { } public void reset() { - dFlag = false; - op = null; - slot = null; + dFlag[0] = 0; + objRefs[KMOPERATION] = null; + objRefs[SLOT] = null; Util.arrayFillNonAtomic( data, (short) 0, (short) data.length, (byte) 0); } private void dataUpdated() { - dFlag = true; + dFlag[0] = 1; } public void release() { - Object[] ops = ((Object[]) slot[REFS]); + Object[] slots = (Object[]) objRefs[SLOT]; + Object[] ops = ((Object[]) slots[REFS]); ((KMOperation) ops[OPERATION]).abort(); JCSystem.beginTransaction(); Util.arrayFillNonAtomic( - (byte[]) slot[0], (short) 0, (short) ((byte[]) slot[0]).length, (byte) 0); + (byte[]) slots[0], (short) 0, (short) ((byte[]) slots[0]).length, (byte) 0); ops[OPERATION] = null; JCSystem.commitTransaction(); reset(); } public short getHandle() { - return Util.getShort(KMOperationState.data, OP_HANDLE); + return Util.getShort(data, OP_HANDLE); } public short getPurpose() { @@ -141,14 +147,14 @@ public void setPurpose(byte purpose) { dataUpdated(); } - public void setOperation(KMOperation operation) { - op = operation; + public void setOperation(KMOperation opr) { + objRefs[KMOPERATION] = opr; dataUpdated(); persist(); } public KMOperation getOperation() { - return op; + return (KMOperation) objRefs[KMOPERATION]; } public boolean isAuthPerOperationReqd() { diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 94bde080..b88173e4 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -86,10 +86,10 @@ public class KMRepository implements KMUpgradable { // Class Attributes private Object[] operationStateTable; private byte[] heap; - private short heapIndex; + private short[] heapIndex; private byte[] dataTable; - private short dataIndex; - private short reclaimIndex; + private short[] dataIndex; + private short[] reclaimIndex; // Singleton instance private static KMRepository repository; @@ -99,10 +99,14 @@ public static KMRepository instance() { } public KMRepository(boolean isUpgrading) { - newDataTable(isUpgrading); heap = JCSystem.makeTransientByteArray(HEAP_SIZE, JCSystem.CLEAR_ON_RESET); - heapIndex = 0; - reclaimIndex = HEAP_SIZE; + heapIndex = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); + reclaimIndex = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); + dataIndex = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); + heapIndex[0] = (short) 0; + reclaimIndex[0] = HEAP_SIZE; + dataIndex[0] = (short) 0; + newDataTable(isUpgrading); operationStateTable = new Object[MAX_OPS]; // create and initialize operation state table. //First byte in the operation handle buffer denotes whether the operation is @@ -309,9 +313,9 @@ public void onProcess() { } public void clean() { - Util.arrayFillNonAtomic(heap, (short) 0, heapIndex, (byte) 0); - heapIndex = 0; - reclaimIndex = HEAP_SIZE; + Util.arrayFillNonAtomic(heap, (short) 0, heapIndex[0], (byte) 0); + heapIndex[0] = (short) 0; + reclaimIndex[0] = HEAP_SIZE; } public void onDeselect() { @@ -324,46 +328,46 @@ public void onSelect() { // This function uses memory from the back of the heap(transient memory). Call // reclaimMemory function immediately after the use. public short allocReclaimableMemory(short length) { - if ((((short) (reclaimIndex - length)) <= heapIndex) + if ((((short) (reclaimIndex[0] - length)) <= heapIndex[0]) || (length >= HEAP_SIZE / 2)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } - reclaimIndex -= length; - return reclaimIndex; + reclaimIndex[0] -= length; + return reclaimIndex[0]; } // Reclaims the memory back. public void reclaimMemory(short length) { - if (reclaimIndex < heapIndex) { + if (reclaimIndex[0] < heapIndex[0]) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } - reclaimIndex += length; + reclaimIndex[0] += length; } public short allocAvailableMemory() { - if (heapIndex >= heap.length) { + if (heapIndex[0] >= heap.length) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } - short index = heapIndex; - heapIndex = (short) heap.length; + short index = heapIndex[0]; + heapIndex[0] = (short) heap.length; return index; } public short alloc(short length) { - if ((((short) (heapIndex + length)) > heap.length) || - (((short) (heapIndex + length)) > reclaimIndex)) { + if ((((short) (heapIndex[0] + length)) > heap.length) || + (((short) (heapIndex[0] + length)) > reclaimIndex[0])) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } - heapIndex += length; - return (short) (heapIndex - length); + heapIndex[0] += length; + return (short) (heapIndex[0] - length); } private short dataAlloc(short length) { - if (((short) (dataIndex + length)) > dataTable.length) { + if (((short) (dataIndex[0] + length)) > dataTable.length) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } - dataIndex += length; - return (short) (dataIndex - length); + dataIndex[0] += length; + return (short) (dataIndex[0] - length); } @@ -371,7 +375,7 @@ private void newDataTable(boolean isUpgrading) { if (!isUpgrading) { if (dataTable == null) { dataTable = new byte[DATA_MEM_SIZE]; - dataIndex = (short) (DATA_INDEX_SIZE * DATA_INDEX_ENTRY_SIZE); + dataIndex[0] = (short) (DATA_INDEX_SIZE * DATA_INDEX_ENTRY_SIZE); } } } @@ -713,7 +717,7 @@ public void onSave(Element ele) { @Override public void onRestore(Element ele) { - dataIndex = ele.readShort(); + dataIndex[0] = ele.readShort(); dataTable = (byte[]) ele.readObject(); } diff --git a/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java b/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java index 1a03b33c..a57ac803 100644 --- a/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java +++ b/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -36,9 +37,10 @@ public class KMVerificationToken extends KMType { public static final byte MAC = 0x04; private static KMVerificationToken prototype; - private static short instPtr; + private short[] instPtr; private KMVerificationToken() { + instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_DESELECT); } public static short exp() { @@ -57,7 +59,7 @@ private static KMVerificationToken proto(short ptr) { if (prototype == null) { prototype = new KMVerificationToken(); } - instPtr = ptr; + prototype.instPtr[0] = ptr; return prototype; } @@ -94,7 +96,7 @@ public static KMVerificationToken cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); } public short length() { From db312d2458f0ae2c388f1e5b37a9ba04b4cea539 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 23 Mar 2021 13:27:02 +0000 Subject: [PATCH 02/16] Modified KMKeymasterApplet code to reduce NVM writes --- .../keymaster/KMAndroidSEProvider.java | 9 +- .../javacard/keymaster/KMJCardSimulator.java | 9 +- .../javacard/keymaster/KMKeymasterApplet.java | 240 +++++++++--------- 3 files changed, 134 insertions(+), 124 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index 369276c7..5e247259 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -1133,13 +1133,12 @@ public void clearCertificateChain() { @Override public void persistPartialCertificateChain(byte[] buf, short offset, short len, short totalLen) { // _____________________________________________________ - // | 2 Bytes | 1 Byte | 3 Bytes | Cert1 | 3 Bytes | Cert2|... - // |_________|________|_________|_______|_________|______| + // | 2 Bytes | 1 Byte | 3 Bytes | Cert1 | Cert2 |... + // |_________|________|_________|_______|________|_______ // First two bytes holds the length of the total buffer. // CBOR format: - // Next single byte holds the array header. - // Next 3 bytes holds the Byte array header with the cert1 length. - // Next 3 bytes holds the Byte array header with the cert2 length. + // Next single byte holds the byte string header. + // Next 3 bytes holds the total length of the certificate chain. if (totalLen > (short) (CERT_CHAIN_MAX_SIZE - 2)) { KMException.throwIt(KMError.INVALID_INPUT_LENGTH); } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index 20de91c8..c6948e63 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -1203,13 +1203,12 @@ public void clearCertificateChain() { public void persistPartialCertificateChain(byte[] buf, short offset, short len, short totalLen) { // _____________________________________________________ - // | 2 Bytes | 1 Byte | 3 Bytes | Cert1 | 3 Bytes | Cert2|... - // |_________|________|_________|_______|_________|______| + // | 2 Bytes | 1 Byte | 3 Bytes | Cert1 | Cert2 |... + // |_________|________|_________|_______|________|_______ // First two bytes holds the length of the total buffer. // CBOR format: - // Next single byte holds the array header. - // Next 3 bytes holds the Byte array header with the cert1 length. - // Next 3 bytes holds the Byte array header with the cert2 length. + // Next single byte holds the byte string header. + // Next 3 bytes holds the total length of the certificate chain. if (totalLen > (short) (CERT_CHAIN_MAX_SIZE - 2)) { KMException.throwIt(KMError.INVALID_INPUT_LENGTH); } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 59af95b6..d6ace193 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -170,6 +170,11 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe private static final byte AES_GCM_NONCE_LENGTH = 12; // ComputeHMAC constants private static final short HMAC_SHARED_PARAM_MAX_SIZE = 64; + // Maximum certificate size. + private static final short MAX_CERT_SIZE = 2048; + // Buffer constants. + private static final short BUF_START_OFFSET = 0; + private static final short BUF_LEN_OFFSET = 2; // Keymaster Applet attributes protected static byte keymasterState = ILLEGAL_STATE; @@ -177,13 +182,11 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe protected static KMDecoder decoder; protected static KMRepository repository; protected static KMSEProvider seProvider; - protected static byte[] buffer; - protected static short bufferLength; - protected static short bufferStartOffset; + protected static Object[] bufferRef; + protected static short[] bufferProp; protected static short[] tmpVariables; protected static short[] data; - protected byte provisionStatus = NOT_PROVISIONED; - protected static final short MAX_CERT_SIZE = 2048; + protected static byte[] provisionStatus; /** * Registers this applet. @@ -192,9 +195,7 @@ protected KMKeymasterApplet(KMSEProvider seImpl) { seProvider = seImpl; boolean isUpgrading = seImpl.isUpgrading(); repository = new KMRepository(isUpgrading); - data = JCSystem.makeTransientShortArray((short) DATA_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); - tmpVariables = - JCSystem.makeTransientShortArray((short) TMP_VARIABLE_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); + initializeTransientArrays(); if (!isUpgrading) { keymasterState = KMKeymasterApplet.INIT_STATE; seProvider.createMasterKey((short) (KMRepository.MASTER_KEY_SIZE * 8)); @@ -204,6 +205,17 @@ protected KMKeymasterApplet(KMSEProvider seImpl) { decoder = new KMDecoder(); } + private void initializeTransientArrays() { + data = JCSystem.makeTransientShortArray((short) DATA_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); + bufferRef = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET); + bufferProp = JCSystem.makeTransientShortArray((short) 4, JCSystem.CLEAR_ON_RESET); + provisionStatus = JCSystem.makeTransientByteArray((short) 1, JCSystem.CLEAR_ON_RESET); + tmpVariables = + JCSystem.makeTransientShortArray((short) TMP_VARIABLE_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); + bufferProp[BUF_START_OFFSET] = 0; + bufferProp[BUF_LEN_OFFSET] = 0; + provisionStatus[0] = NOT_PROVISIONED; + } /** * Selects this applet. * @@ -321,43 +333,43 @@ public void process(APDU apdu) { if (!(apduIns > INS_BEGIN_KM_CMD && apduIns < INS_END_KM_CMD)) { ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } - buffer = repository.getHeap(); + bufferRef[0] = repository.getHeap(); // Process the apdu if (keymasterState == KMKeymasterApplet.IN_PROVISION_STATE) { switch (apduIns) { case INS_PROVISION_ATTESTATION_KEY_CMD: processProvisionAttestationKey(apdu); - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_KEY; + provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_KEY; sendError(apdu, KMError.OK); return; case INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD: processProvisionAttestationCertChainCmd(apdu); - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_CHAIN; + provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_CHAIN; sendError(apdu, KMError.OK); return; case INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD: processProvisionAttestationCertParams(apdu); - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_PARAMS; + provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_PARAMS; sendError(apdu, KMError.OK); return; case INS_PROVISION_ATTEST_IDS_CMD: processProvisionAttestIdsCmd(apdu); - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTEST_IDS; + provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTEST_IDS; sendError(apdu, KMError.OK); return; case INS_PROVISION_PRESHARED_SECRET_CMD: processProvisionSharedSecretCmd(apdu); - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_PRESHARED_SECRET; + provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_PRESHARED_SECRET; sendError(apdu, KMError.OK); return; case INS_LOCK_PROVISIONING_CMD: if (isProvisioningComplete()) { - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED; + provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED; keymasterState = KMKeymasterApplet.ACTIVE_STATE; sendError(apdu, KMError.OK); } else { @@ -376,7 +388,7 @@ public void process(APDU apdu) { ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); } processSetBootParamsCmd(apdu); - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_BOOT_PARAM; + provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_BOOT_PARAM; seProvider.clearDeviceBooted(false); sendError(apdu, KMError.OK); return; @@ -489,11 +501,11 @@ private void generateUniqueOperationHandle(byte[] buf, short offset, short len) } private boolean isProvisioningComplete() { - if ((0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_KEY)) - && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) - && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) - && (0 != (provisionStatus & PROVISION_STATUS_PRESHARED_SECRET)) - && (0 != (provisionStatus & PROVISION_STATUS_BOOT_PARAM))) { + if ((0 != (provisionStatus[0] & PROVISION_STATUS_ATTESTATION_KEY)) + && (0 != (provisionStatus[0] & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) + && (0 != (provisionStatus[0] & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) + && (0 != (provisionStatus[0] & PROVISION_STATUS_PRESHARED_SECRET)) + && (0 != (provisionStatus[0] & PROVISION_STATUS_BOOT_PARAM))) { return true; } else { return false; @@ -521,9 +533,9 @@ private void processDeviceLockedCmd(APDU apdu) { tmpVariables[1] = KMVerificationToken.exp(); KMArray.cast(tmpVariables[0]).add((short) 1, tmpVariables[1]); // Decode the arguments - tmpVariables[0] = decoder.decode(tmpVariables[0], buffer, bufferStartOffset, bufferLength); + tmpVariables[0] = decoder.decode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); tmpVariables[1] = KMArray.cast(tmpVariables[0]).get((short) 0); tmpVariables[1] = KMInteger.cast(tmpVariables[1]).getByte(); @@ -558,14 +570,14 @@ private void resetData() { * Sends a response, may be extended response, as requested by the command. */ public static void sendOutgoing(APDU apdu) { - if (((short) (bufferLength + bufferStartOffset)) > ((short) repository + if (((short) (bufferProp[BUF_LEN_OFFSET] + bufferProp[BUF_START_OFFSET])) > ((short) repository .getHeap().length)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // Send data apdu.setOutgoing(); - apdu.setOutgoingLength(bufferLength); - apdu.sendBytesLong(buffer, bufferStartOffset, bufferLength); + apdu.setOutgoingLength(bufferProp[BUF_LEN_OFFSET]); + apdu.sendBytesLong((byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); } /** @@ -575,12 +587,12 @@ public static void receiveIncoming(APDU apdu) { byte[] srcBuffer = apdu.getBuffer(); short recvLen = apdu.setIncomingAndReceive(); short srcOffset = apdu.getOffsetCdata(); - bufferLength = apdu.getIncomingLength(); - bufferStartOffset = repository.allocReclaimableMemory(bufferLength); - short index = bufferStartOffset; + bufferProp[BUF_LEN_OFFSET] = apdu.getIncomingLength(); + bufferProp[BUF_START_OFFSET] = repository.allocReclaimableMemory(bufferProp[BUF_LEN_OFFSET]); + short index = bufferProp[BUF_START_OFFSET]; - while (recvLen > 0 && ((short) (index - bufferStartOffset) < bufferLength)) { - Util.arrayCopyNonAtomic(srcBuffer, srcOffset, buffer, index, recvLen); + while (recvLen > 0 && ((short) (index - bufferProp[BUF_START_OFFSET]) < bufferProp[BUF_LEN_OFFSET])) { + Util.arrayCopyNonAtomic(srcBuffer, srcOffset, (byte[]) bufferRef[0], index, recvLen); index += recvLen; recvLen = apdu.receiveBytes(srcOffset); } @@ -604,9 +616,9 @@ private void processGetHwInfoCmd(APDU apdu) { JavacardKeymasterDevice, (short) 0, (short) JavacardKeymasterDevice.length)); resp.add((short) 2, KMByteBlob.instance(Google, (short) 0, (short) Google.length)); - bufferStartOffset = repository.allocAvailableMemory(); - // Encode the response - actual bufferLength is 86 - bufferLength = encoder.encode(respPtr, buffer, bufferStartOffset); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); + // Encode the response - actual bufferProp[BUF_LEN_OFFSET] is 86 + bufferProp[BUF_LEN_OFFSET] = encoder.encode(respPtr, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); // send buffer to master sendOutgoing(apdu); } @@ -618,9 +630,9 @@ private void processAddRngEntropyCmd(APDU apdu) { short argsProto = KMArray.instance((short) 1); KMArray.cast(argsProto).add((short) 0, KMByteBlob.exp()); // Decode the argument - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); // Process KMByteBlob blob = KMByteBlob.cast(KMArray.cast(args).get((short) 0)); @@ -638,14 +650,14 @@ private void processGetCertChainCmd(APDU apdu) { // Add arrayHeader and KMError.OK tmpVariables[0] += 2; tmpVariables[1] = KMByteBlob.instance(tmpVariables[0]); - buffer = KMByteBlob.cast(tmpVariables[1]).getBuffer(); - bufferStartOffset = KMByteBlob.cast(tmpVariables[1]).getStartOff(); - bufferLength = KMByteBlob.cast(tmpVariables[1]).length(); + bufferRef[0] = KMByteBlob.cast(tmpVariables[1]).getBuffer(); + bufferProp[BUF_START_OFFSET] = KMByteBlob.cast(tmpVariables[1]).getStartOff(); + bufferProp[BUF_LEN_OFFSET] = KMByteBlob.cast(tmpVariables[1]).length(); // read the cert chain from non-volatile memory. Cert chain is already in // CBOR format. - seProvider.readCertificateChain(buffer, (short) (bufferStartOffset + 2)); + seProvider.readCertificateChain((byte[]) bufferRef[0], (short) (bufferProp[BUF_START_OFFSET] + 2)); // Encode cert chain. - encoder.encodeCertChain(buffer, bufferStartOffset, bufferLength); + encoder.encodeCertChain((byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); sendOutgoing(apdu); } @@ -657,9 +669,9 @@ private void processProvisionAttestationCertParams(APDU apdu) { KMArray.cast(argsProto).add((short) 0, blob); // Cert - DER encoded issuer KMArray.cast(argsProto).add((short) 1, blob); // Cert - Expiry Time // Decode the argument. - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); // save issuer - DER Encoded tmpVariables[0] = KMArray.cast(args).get((short) 0); @@ -685,21 +697,21 @@ private void processProvisionAttestationCertChainCmd(APDU apdu) { byte[] srcBuffer = apdu.getBuffer(); short recvLen = apdu.setIncomingAndReceive(); short srcOffset = apdu.getOffsetCdata(); - bufferLength = apdu.getIncomingLength(); - bufferStartOffset = repository.alloc(bufferLength); + bufferProp[BUF_LEN_OFFSET] = apdu.getIncomingLength(); + bufferProp[BUF_START_OFFSET] = repository.alloc(bufferProp[BUF_LEN_OFFSET]); short bytesRead = 0; - Util.arrayCopyNonAtomic(srcBuffer, srcOffset, buffer, bufferStartOffset, + Util.arrayCopyNonAtomic(srcBuffer, srcOffset, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], recvLen); // tmpVariables[1] holds the total length + Header length. - tmpVariables[1] = decoder.readCertificateChainLengthAndHeaderLen(buffer, - bufferStartOffset, recvLen); - while (recvLen > 0 && ((short) bytesRead <= bufferLength)) { - seProvider.persistPartialCertificateChain(buffer, bufferStartOffset, - recvLen, bufferLength); + tmpVariables[1] = decoder.readCertificateChainLengthAndHeaderLen((byte[]) bufferRef[0], + bufferProp[BUF_START_OFFSET], recvLen); + while (recvLen > 0 && ((short) bytesRead <= bufferProp[BUF_LEN_OFFSET])) { + seProvider.persistPartialCertificateChain((byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], + recvLen, bufferProp[BUF_LEN_OFFSET]); bytesRead += recvLen; recvLen = apdu.receiveBytes(srcOffset); if (recvLen > 0) { - Util.arrayCopyNonAtomic(srcBuffer, srcOffset, buffer, bufferStartOffset, + Util.arrayCopyNonAtomic(srcBuffer, srcOffset, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], recvLen); } } @@ -722,9 +734,9 @@ private void processProvisionAttestationKey(APDU apdu) { KMArray.cast(argsProto).add((short) 2, blob); // Decode the argument - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); // key params should have os patch, os version and verified root of trust data[KEY_PARAMETERS] = KMArray.cast(args).get((short) 0); @@ -787,9 +799,9 @@ private void processProvisionAttestIdsCmd(APDU apdu) { short argsProto = KMArray.instance((short) 1); KMArray.cast(argsProto).add((short) 0, keyparams); // Decode the argument. - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[KEY_PARAMETERS] = KMArray.cast(args).get((short) 0); // persist attestation Ids - if any is missing then exception occurs @@ -810,9 +822,9 @@ private void processProvisionSharedSecretCmd(APDU apdu) { short argsProto = KMArray.instance((short) 1); KMArray.cast(argsProto).add((short) 0, blob); // Decode the argument. - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); tmpVariables[0] = KMArray.cast(args).get((short) 0); if (tmpVariables[0] != KMType.INVALID_VALUE @@ -829,10 +841,10 @@ private void processProvisionSharedSecretCmd(APDU apdu) { private void processGetProvisionStatusCmd(APDU apdu) { tmpVariables[0] = KMArray.instance((short) 2); KMArray.cast(tmpVariables[0]).add((short) 0, KMInteger.uint_16(KMError.OK)); - KMArray.cast(tmpVariables[0]).add((short) 1, KMInteger.uint_16(provisionStatus)); + KMArray.cast(tmpVariables[0]).add((short) 1, KMInteger.uint_16(provisionStatus[0])); - bufferStartOffset = repository.allocAvailableMemory(); - bufferLength = encoder.encode(tmpVariables[0], buffer, bufferStartOffset); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -884,9 +896,9 @@ private void processGetKeyCharacteristicsCmd(APDU apdu) { KMArray.cast(tmpVariables[0]).add((short) 1, KMByteBlob.exp()); KMArray.cast(tmpVariables[0]).add((short) 2, KMByteBlob.exp()); // Decode the arguments - tmpVariables[0] = decoder.decode(tmpVariables[0], buffer, bufferStartOffset, bufferLength); + tmpVariables[0] = decoder.decode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[KEY_BLOB] = KMArray.cast(tmpVariables[0]).get((short) 0); data[APP_ID] = KMArray.cast(tmpVariables[0]).get((short) 1); @@ -906,9 +918,9 @@ private void processGetKeyCharacteristicsCmd(APDU apdu) { KMArray.cast(tmpVariables[0]).add((short) 0, KMInteger.uint_16(KMError.OK)); KMArray.cast(tmpVariables[0]).add((short) 1, data[KEY_CHARACTERISTICS]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[0], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -923,9 +935,9 @@ private void processGetHmacSharingParamCmd(APDU apdu) { KMArray.cast(tmpVariables[3]).add((short) 0, KMInteger.uint_16(KMError.OK)); KMArray.cast(tmpVariables[3]).add((short) 1, tmpVariables[2]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[3], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[3], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -944,9 +956,9 @@ private void processDeleteKeyCmd(APDU apdu) { short argsProto = KMArray.instance((short) 1); KMArray.cast(argsProto).add((short) 0, KMByteBlob.exp()); // Decode the argument - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); // Process data[KEY_BLOB] = KMArray.cast(args).get((short) 0); @@ -985,9 +997,9 @@ private void processComputeSharedHmacCmd(APDU apdu) { tmpVariables[2] = KMArray.instance((short) 1); KMArray.cast(tmpVariables[2]).add((short) 0, tmpVariables[0]); // Vector of hmac params // Decode the arguments - tmpVariables[0] = decoder.decode(tmpVariables[2], buffer, bufferStartOffset, bufferLength); + tmpVariables[0] = decoder.decode(tmpVariables[2], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[HMAC_SHARING_PARAMS] = KMArray.cast(tmpVariables[0]).get((short) 0); // Concatenate HMAC Params @@ -1089,9 +1101,9 @@ private void processComputeSharedHmacCmd(APDU apdu) { KMArray.cast(tmpVariables[0]).add((short) 0, KMInteger.uint_16(KMError.OK)); KMArray.cast(tmpVariables[0]).add((short) 1, tmpVariables[1]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[0], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -1129,9 +1141,9 @@ private void processUpgradeKeyCmd(APDU apdu) { KMArray.cast(tmpVariables[1]).add((short) 0, KMByteBlob.exp()); // Key Blob KMArray.cast(tmpVariables[1]).add((short) 1, tmpVariables[2]); // Key Params // Decode the arguments - tmpVariables[2] = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + tmpVariables[2] = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[KEY_BLOB] = KMArray.cast(tmpVariables[2]).get((short) 0); data[KEY_PARAMETERS] = KMArray.cast(tmpVariables[2]).get((short) 1); @@ -1167,9 +1179,9 @@ private void processUpgradeKeyCmd(APDU apdu) { KMArray.cast(tmpVariables[0]).add((short) 0, KMInteger.uint_16(KMError.OK)); KMArray.cast(tmpVariables[0]).add((short) 1, data[KEY_BLOB]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[0], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -1198,9 +1210,9 @@ private void processImportWrappedKeyCmd(APDU apdu) { KMArray.cast(tmpVariables[1]).add((short) 10, KMInteger.exp()); // Password Sid KMArray.cast(tmpVariables[1]).add((short) 11, KMInteger.exp()); // Biometric Sid // Decode the arguments - short args = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); // Step -0 - check whether the key format and algorithm supported // read algorithm @@ -1351,9 +1363,9 @@ private void processAttestKeyCmd(APDU apdu) { KMArray.cast(argsProto).add((short) 1, keyParams); // Decode the argument - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[KEY_BLOB] = KMArray.cast(args).get((short) 0); data[KEY_PARAMETERS] = KMArray.cast(args).get((short) 1); @@ -1435,14 +1447,14 @@ private void processAttestKeyCmd(APDU apdu) { // buffer for cert - we allocate 2KBytes buffer // make this buffer size configurable tmpVariables[3] = KMByteBlob.instance(MAX_CERT_SIZE); - buffer = KMByteBlob.cast(tmpVariables[3]).getBuffer(); - bufferStartOffset = KMByteBlob.cast(tmpVariables[3]).getStartOff(); - bufferLength = KMByteBlob.cast(tmpVariables[3]).length(); - cert.buffer(buffer, bufferStartOffset, bufferLength); + bufferRef[0] = KMByteBlob.cast(tmpVariables[3]).getBuffer(); + bufferProp[BUF_START_OFFSET] = KMByteBlob.cast(tmpVariables[3]).getStartOff(); + bufferProp[BUF_LEN_OFFSET] = KMByteBlob.cast(tmpVariables[3]).length(); + cert.buffer((byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); cert.build(); - bufferStartOffset = - encoder.encodeCert(buffer, bufferStartOffset, cert.getCertStart(), cert.getCertLength()); - bufferLength = (short) (cert.getCertLength() + (cert.getCertStart() - bufferStartOffset)); + bufferProp[BUF_START_OFFSET] = + encoder.encodeCert((byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], cert.getCertStart(), cert.getCertLength()); + bufferProp[BUF_LEN_OFFSET] = (short) (cert.getCertLength() + (cert.getCertStart() - bufferProp[BUF_START_OFFSET])); sendOutgoing(apdu); } @@ -1540,9 +1552,9 @@ private void processAbortOperationCmd(APDU apdu) { receiveIncoming(apdu); tmpVariables[1] = KMArray.instance((short) 1); KMArray.cast(tmpVariables[1]).add((short) 0, KMInteger.exp()); - tmpVariables[2] = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + tmpVariables[2] = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[OP_HANDLE] = KMArray.cast(tmpVariables[2]).get((short) 0); KMOperationState op = repository.findOperation(data[OP_HANDLE]); @@ -1568,9 +1580,9 @@ private void processFinishOperationCmd(APDU apdu) { tmpVariables[4] = KMVerificationToken.exp(); KMArray.cast(tmpVariables[1]).add((short) 5, tmpVariables[4]); // Decode the arguments - tmpVariables[2] = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + tmpVariables[2] = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[OP_HANDLE] = KMArray.cast(tmpVariables[2]).get((short) 0); data[KEY_PARAMETERS] = KMArray.cast(tmpVariables[2]).get((short) 1); @@ -1610,9 +1622,9 @@ private void processFinishOperationCmd(APDU apdu) { KMArray.cast(tmpVariables[2]).add((short) 1, tmpVariables[1]); KMArray.cast(tmpVariables[2]).add((short) 2, data[OUTPUT_DATA]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[2], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[2], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -1982,9 +1994,9 @@ private void processUpdateOperationCmd(APDU apdu) { tmpVariables[4] = KMVerificationToken.exp(); KMArray.cast(tmpVariables[1]).add((short) 4, tmpVariables[4]); // Decode the arguments - tmpVariables[2] = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + tmpVariables[2] = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[OP_HANDLE] = KMArray.cast(tmpVariables[2]).get((short) 0); data[KEY_PARAMETERS] = KMArray.cast(tmpVariables[2]).get((short) 1); @@ -2093,9 +2105,9 @@ private void processUpdateOperationCmd(APDU apdu) { KMArray.cast(tmpVariables[2]).add((short) 2, tmpVariables[1]); KMArray.cast(tmpVariables[2]).add((short) 3, data[OUTPUT_DATA]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[2], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[2], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -2113,9 +2125,9 @@ private void processBeginOperationCmd(APDU apdu) { tmpVariables[3] = KMHardwareAuthToken.exp(); KMArray.cast(tmpVariables[1]).add((short) 3, tmpVariables[3]); // Decode the arguments - args = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + args = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[KEY_PARAMETERS] = KMArray.cast(args).get((short) 2); data[KEY_BLOB] = KMArray.cast(args).get((short) 1); @@ -2198,9 +2210,9 @@ private void processBeginOperationCmd(APDU apdu) { KMArray.cast(tmpVariables[0]).add((short) 1, tmpVariables[1]); KMArray.cast(tmpVariables[0]).add((short) 2, data[OP_HANDLE]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[0], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -2738,9 +2750,9 @@ private void processImportKeyCmd(APDU apdu) { KMArray.cast(tmpVariables[1]).add((short) 1, KMEnum.instance(KMType.KEY_FORMAT)); KMArray.cast(tmpVariables[1]).add((short) 2, KMByteBlob.exp()); // Decode the arguments - tmpVariables[2] = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + tmpVariables[2] = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[KEY_PARAMETERS] = KMArray.cast(tmpVariables[2]).get((short) 0); tmpVariables[3] = KMArray.cast(tmpVariables[2]).get((short) 1); @@ -2808,9 +2820,9 @@ private void importKey(APDU apdu, byte[] scratchPad) { KMArray.cast(tmpVariables[0]).add((short) 1, data[KEY_BLOB]); KMArray.cast(tmpVariables[0]).add((short) 2, data[KEY_CHARACTERISTICS]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[0], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -3153,9 +3165,9 @@ private void processSetBootParamsCmd(APDU apdu) { KMArray.cast(argsProto).add((short) 6, tmpVariables[6]); KMArray.cast(argsProto).add((short) 7, tmpVariables[7]); // Decode the arguments - short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); + short args = decoder.decode(argsProto, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); tmpVariables[0] = KMArray.cast(args).get((short) 0); tmpVariables[1] = KMArray.cast(args).get((short) 1); @@ -3230,9 +3242,9 @@ private static void processGenerateKey(APDU apdu) { tmpVariables[1] = KMArray.instance((short) 1); KMArray.cast(tmpVariables[1]).add((short) 0, tmpVariables[0]); // Decode the argument - tmpVariables[2] = decoder.decode(tmpVariables[1], buffer, bufferStartOffset, bufferLength); + tmpVariables[2] = decoder.decode(tmpVariables[1], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], bufferProp[BUF_LEN_OFFSET]); //reclaim memory - repository.reclaimMemory(bufferLength); + repository.reclaimMemory(bufferProp[BUF_LEN_OFFSET]); data[KEY_PARAMETERS] = KMArray.cast(tmpVariables[2]).get((short) 0); // Check if EarlyBootEnded tag is present. @@ -3310,9 +3322,9 @@ private static void processGenerateKey(APDU apdu) { KMArray.cast(tmpVariables[0]).add((short) 1, data[KEY_BLOB]); KMArray.cast(tmpVariables[0]).add((short) 2, data[KEY_CHARACTERISTICS]); - bufferStartOffset = repository.allocAvailableMemory(); + bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); // Encode the response - bufferLength = encoder.encode(tmpVariables[0], buffer, bufferStartOffset); + bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); sendOutgoing(apdu); } @@ -3815,8 +3827,8 @@ private static short deriveKey(byte[] scratchPad) { } private static void sendError(APDU apdu, short err) { - bufferStartOffset = repository.alloc((short) 2); - bufferLength = encoder.encodeError(err, buffer, bufferStartOffset, (short) 5); + bufferProp[BUF_START_OFFSET] = repository.alloc((short) 2); + bufferProp[BUF_LEN_OFFSET] = encoder.encodeError(err, (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET], (short) 5); sendOutgoing(apdu); } From a239fe0cd6f4615fc525e538ac3cdb9c51fa9ecf Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 23 Mar 2021 21:16:08 +0000 Subject: [PATCH 03/16] Fix issue with Applet upgrade after NVM write optimization --- .../src/com/android/javacard/keymaster/KMAndroidSEApplet.java | 4 ++-- .../src/com/android/javacard/keymaster/KMOperationImpl.java | 2 ++ Applet/src/com/android/javacard/keymaster/KMRepository.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index 7c6f31fe..cd9d8caa 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -47,7 +47,7 @@ public void onConsolidate() { @Override public void onRestore(Element element) { element.initRead(); - provisionStatus = element.readByte(); + provisionStatus[0] = element.readByte(); keymasterState = element.readByte(); repository.onRestore(element); seProvider.onRestore(element); @@ -68,7 +68,7 @@ public Element onSave() { // Create element. Element element = UpgradeManager.createElement(Element.TYPE_SIMPLE, primitiveCount, objectCount); - element.write(provisionStatus); + element.write(provisionStatus[0]); element.write(keymasterState); repository.onSave(element); seProvider.onSave(element); diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index 502f3fb5..b5ef9026 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -103,7 +103,9 @@ public short update(byte[] inputDataBuf, short inputDataStart, outputDataBuf, outputDataStart); if (cipherAlg == KMType.AES && blockMode == KMType.GCM) { // Every time Block size data is stored as intermediate result. + JCSystem.beginTransaction(); aesGcmUpdatedLen += (short) (inputDataLength - len); + JCSystem.commitTransaction(); } return len; } diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index b88173e4..a387b9ab 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -711,7 +711,7 @@ public void setBootState(byte state) { @Override public void onSave(Element ele) { - ele.write(dataIndex); + ele.write(dataIndex[0]); ele.write(dataTable); } From 0841aeb67e6791aef4e901e0f05ac09838ad1054 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Wed, 24 Mar 2021 16:32:18 +0000 Subject: [PATCH 04/16] Fixed the issue with Applet upgrade --- .../javacard/keymaster/KMAndroidSEApplet.java | 4 +-- .../javacard/keymaster/KMKeymasterApplet.java | 30 +++++++++---------- .../javacard/keymaster/KMRepository.java | 16 +++++----- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index cd9d8caa..7c6f31fe 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -47,7 +47,7 @@ public void onConsolidate() { @Override public void onRestore(Element element) { element.initRead(); - provisionStatus[0] = element.readByte(); + provisionStatus = element.readByte(); keymasterState = element.readByte(); repository.onRestore(element); seProvider.onRestore(element); @@ -68,7 +68,7 @@ public Element onSave() { // Create element. Element element = UpgradeManager.createElement(Element.TYPE_SIMPLE, primitiveCount, objectCount); - element.write(provisionStatus[0]); + element.write(provisionStatus); element.write(keymasterState); repository.onSave(element); seProvider.onSave(element); diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index d6ace193..643a29a4 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -186,7 +186,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe protected static short[] bufferProp; protected static short[] tmpVariables; protected static short[] data; - protected static byte[] provisionStatus; + protected static byte provisionStatus = NOT_PROVISIONED; /** * Registers this applet. @@ -209,12 +209,10 @@ private void initializeTransientArrays() { data = JCSystem.makeTransientShortArray((short) DATA_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); bufferRef = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET); bufferProp = JCSystem.makeTransientShortArray((short) 4, JCSystem.CLEAR_ON_RESET); - provisionStatus = JCSystem.makeTransientByteArray((short) 1, JCSystem.CLEAR_ON_RESET); tmpVariables = JCSystem.makeTransientShortArray((short) TMP_VARIABLE_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); bufferProp[BUF_START_OFFSET] = 0; bufferProp[BUF_LEN_OFFSET] = 0; - provisionStatus[0] = NOT_PROVISIONED; } /** * Selects this applet. @@ -339,37 +337,37 @@ public void process(APDU apdu) { switch (apduIns) { case INS_PROVISION_ATTESTATION_KEY_CMD: processProvisionAttestationKey(apdu); - provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_KEY; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_KEY; sendError(apdu, KMError.OK); return; case INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD: processProvisionAttestationCertChainCmd(apdu); - provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_CHAIN; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_CHAIN; sendError(apdu, KMError.OK); return; case INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD: processProvisionAttestationCertParams(apdu); - provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_PARAMS; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTESTATION_CERT_PARAMS; sendError(apdu, KMError.OK); return; case INS_PROVISION_ATTEST_IDS_CMD: processProvisionAttestIdsCmd(apdu); - provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_ATTEST_IDS; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_ATTEST_IDS; sendError(apdu, KMError.OK); return; case INS_PROVISION_PRESHARED_SECRET_CMD: processProvisionSharedSecretCmd(apdu); - provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_PRESHARED_SECRET; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_PRESHARED_SECRET; sendError(apdu, KMError.OK); return; case INS_LOCK_PROVISIONING_CMD: if (isProvisioningComplete()) { - provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_PROVISIONING_LOCKED; keymasterState = KMKeymasterApplet.ACTIVE_STATE; sendError(apdu, KMError.OK); } else { @@ -388,7 +386,7 @@ public void process(APDU apdu) { ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); } processSetBootParamsCmd(apdu); - provisionStatus[0] |= KMKeymasterApplet.PROVISION_STATUS_BOOT_PARAM; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_BOOT_PARAM; seProvider.clearDeviceBooted(false); sendError(apdu, KMError.OK); return; @@ -501,11 +499,11 @@ private void generateUniqueOperationHandle(byte[] buf, short offset, short len) } private boolean isProvisioningComplete() { - if ((0 != (provisionStatus[0] & PROVISION_STATUS_ATTESTATION_KEY)) - && (0 != (provisionStatus[0] & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) - && (0 != (provisionStatus[0] & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) - && (0 != (provisionStatus[0] & PROVISION_STATUS_PRESHARED_SECRET)) - && (0 != (provisionStatus[0] & PROVISION_STATUS_BOOT_PARAM))) { + if ((0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_KEY)) + && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) + && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) + && (0 != (provisionStatus & PROVISION_STATUS_PRESHARED_SECRET)) + && (0 != (provisionStatus & PROVISION_STATUS_BOOT_PARAM))) { return true; } else { return false; @@ -841,7 +839,7 @@ private void processProvisionSharedSecretCmd(APDU apdu) { private void processGetProvisionStatusCmd(APDU apdu) { tmpVariables[0] = KMArray.instance((short) 2); KMArray.cast(tmpVariables[0]).add((short) 0, KMInteger.uint_16(KMError.OK)); - KMArray.cast(tmpVariables[0]).add((short) 1, KMInteger.uint_16(provisionStatus[0])); + KMArray.cast(tmpVariables[0]).add((short) 1, KMInteger.uint_16(provisionStatus)); bufferProp[BUF_START_OFFSET] = repository.allocAvailableMemory(); bufferProp[BUF_LEN_OFFSET] = encoder.encode(tmpVariables[0], (byte[]) bufferRef[0], bufferProp[BUF_START_OFFSET]); diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index a387b9ab..07caec72 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -88,7 +88,7 @@ public class KMRepository implements KMUpgradable { private byte[] heap; private short[] heapIndex; private byte[] dataTable; - private short[] dataIndex; + private short dataIndex; private short[] reclaimIndex; // Singleton instance @@ -102,10 +102,8 @@ public KMRepository(boolean isUpgrading) { heap = JCSystem.makeTransientByteArray(HEAP_SIZE, JCSystem.CLEAR_ON_RESET); heapIndex = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); reclaimIndex = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); - dataIndex = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); heapIndex[0] = (short) 0; reclaimIndex[0] = HEAP_SIZE; - dataIndex[0] = (short) 0; newDataTable(isUpgrading); operationStateTable = new Object[MAX_OPS]; // create and initialize operation state table. @@ -363,11 +361,11 @@ public short alloc(short length) { } private short dataAlloc(short length) { - if (((short) (dataIndex[0] + length)) > dataTable.length) { + if (((short) (dataIndex + length)) > dataTable.length) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } - dataIndex[0] += length; - return (short) (dataIndex[0] - length); + dataIndex += length; + return (short) (dataIndex - length); } @@ -375,7 +373,7 @@ private void newDataTable(boolean isUpgrading) { if (!isUpgrading) { if (dataTable == null) { dataTable = new byte[DATA_MEM_SIZE]; - dataIndex[0] = (short) (DATA_INDEX_SIZE * DATA_INDEX_ENTRY_SIZE); + dataIndex = (short) (DATA_INDEX_SIZE * DATA_INDEX_ENTRY_SIZE); } } } @@ -711,13 +709,13 @@ public void setBootState(byte state) { @Override public void onSave(Element ele) { - ele.write(dataIndex[0]); + ele.write(dataIndex); ele.write(dataTable); } @Override public void onRestore(Element ele) { - dataIndex[0] = ele.readShort(); + dataIndex = ele.readShort(); dataTable = (byte[]) ele.readObject(); } From 6812eae561f933d672b47d0d776a89400a00ec1d Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 25 Mar 2021 11:54:20 +0000 Subject: [PATCH 05/16] created an instanceTable inside KMType and remvoved instPtr from each type file. --- .../android/javacard/keymaster/KMArray.java | 18 +++--- .../android/javacard/keymaster/KMBoolTag.java | 32 +++++----- .../javacard/keymaster/KMByteBlob.java | 16 ++--- .../android/javacard/keymaster/KMByteTag.java | 48 +++++++------- .../android/javacard/keymaster/KMEnum.java | 64 +++++++++---------- .../javacard/keymaster/KMEnumArrayTag.java | 34 +++++----- .../android/javacard/keymaster/KMEnumTag.java | 28 ++++---- .../keymaster/KMHardwareAuthToken.java | 6 +- .../keymaster/KMHmacSharingParameters.java | 6 +- .../android/javacard/keymaster/KMInteger.java | 28 ++++---- .../javacard/keymaster/KMIntegerArrayTag.java | 12 ++-- .../javacard/keymaster/KMIntegerTag.java | 52 ++++++++------- .../keymaster/KMKeyCharacteristics.java | 6 +- .../javacard/keymaster/KMKeyParameters.java | 6 +- .../android/javacard/keymaster/KMType.java | 22 +++++++ .../keymaster/KMVerificationToken.java | 6 +- 16 files changed, 188 insertions(+), 196 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMArray.java b/Applet/src/com/android/javacard/keymaster/KMArray.java index a2de179d..b719af9a 100644 --- a/Applet/src/com/android/javacard/keymaster/KMArray.java +++ b/Applet/src/com/android/javacard/keymaster/KMArray.java @@ -37,17 +37,15 @@ public class KMArray extends KMType { public static final short ANY_ARRAY_LENGTH = 0x1000; private static final short ARRAY_HEADER_SIZE = 4; private static KMArray prototype; - private short[] instPtr; private KMArray() { - instPtr = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMArray proto(short ptr) { if (prototype == null) { prototype = new KMArray(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_ARRAY_OFFSET] = ptr; return prototype; } @@ -91,9 +89,9 @@ public void add(short index, short objPtr) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } Util.setShort( - heap, - (short) (instPtr[0] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2)), - objPtr); + heap, + (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2)), + objPtr); } public short get(short index) { @@ -102,19 +100,19 @@ public short get(short index) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } return Util.getShort( - heap, (short) (instPtr[0] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2))); + heap, (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2))); } public short containedType() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE)); } public short getStartOff() { - return (short) (instPtr[0] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE); + return (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE); } public short length() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + 2)); } public byte[] getBuffer() { diff --git a/Applet/src/com/android/javacard/keymaster/KMBoolTag.java b/Applet/src/com/android/javacard/keymaster/KMBoolTag.java index f0b642c7..04938e39 100644 --- a/Applet/src/com/android/javacard/keymaster/KMBoolTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMBoolTag.java @@ -31,33 +31,31 @@ public class KMBoolTag extends KMTag { private static KMBoolTag prototype; - private short[] instPtr; // The allowed tag keys of type bool tag. private static final short[] tags = { - CALLER_NONCE, - INCLUDE_UNIQUE_ID, - BOOTLOADER_ONLY, - ROLLBACK_RESISTANCE, - NO_AUTH_REQUIRED, - ALLOW_WHILE_ON_BODY, - TRUSTED_USER_PRESENCE_REQUIRED, - TRUSTED_CONFIRMATION_REQUIRED, - UNLOCKED_DEVICE_REQUIRED, - RESET_SINCE_ID_ROTATION, - EARLY_BOOT_ONLY, - DEVICE_UNIQUE_ATTESTATION + CALLER_NONCE, + INCLUDE_UNIQUE_ID, + BOOTLOADER_ONLY, + ROLLBACK_RESISTANCE, + NO_AUTH_REQUIRED, + ALLOW_WHILE_ON_BODY, + TRUSTED_USER_PRESENCE_REQUIRED, + TRUSTED_CONFIRMATION_REQUIRED, + UNLOCKED_DEVICE_REQUIRED, + RESET_SINCE_ID_ROTATION, + EARLY_BOOT_ONLY, + DEVICE_UNIQUE_ATTESTATION }; private KMBoolTag() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMBoolTag proto(short ptr) { if (prototype == null) { prototype = new KMBoolTag(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_BOOL_TAG_OFFSET] = ptr; return prototype; } @@ -91,7 +89,7 @@ public static KMBoolTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_BOOL_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -99,7 +97,7 @@ public short getTagType() { } public byte getVal() { - return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 4)]; + return heap[(short) (instanceTable[KM_BOOL_TAG_OFFSET] + TLV_HEADER_SIZE + 4)]; } // validate the tag key. diff --git a/Applet/src/com/android/javacard/keymaster/KMByteBlob.java b/Applet/src/com/android/javacard/keymaster/KMByteBlob.java index 2c91ac6b..2207e978 100644 --- a/Applet/src/com/android/javacard/keymaster/KMByteBlob.java +++ b/Applet/src/com/android/javacard/keymaster/KMByteBlob.java @@ -29,17 +29,15 @@ public class KMByteBlob extends KMType { private static KMByteBlob prototype; - private short[] instPtr; private KMByteBlob() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMByteBlob proto(short ptr) { if (prototype == null) { prototype = new KMByteBlob(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_BYTE_BLOB_OFFSET] = ptr; return prototype; } @@ -77,7 +75,7 @@ public void add(short index, byte val) { if (index >= len) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } - heap[(short) (instPtr[0] + TLV_HEADER_SIZE + index)] = val; + heap[(short) (instanceTable[KM_BYTE_BLOB_OFFSET] + TLV_HEADER_SIZE + index)] = val; } // Get the byte @@ -86,17 +84,17 @@ public byte get(short index) { if (index >= len) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } - return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + index)]; + return heap[(short) (instanceTable[KM_BYTE_BLOB_OFFSET] + TLV_HEADER_SIZE + index)]; } // Get the start of blob public short getStartOff() { - return (short) (instPtr[0] + TLV_HEADER_SIZE); + return (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + TLV_HEADER_SIZE); } // Get the length of the blob public short length() { - return Util.getShort(heap, (short) (instPtr[0] + 1)); + return Util.getShort(heap, (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + 1)); } // Get the buffer pointer in which blob is contained. @@ -129,8 +127,8 @@ public boolean isValid() { } public void decrementLength(short len) { - short length = Util.getShort(heap, (short) (instPtr[0] + 1)); + short length = Util.getShort(heap, (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + 1)); length = (short) (length - len); - Util.setShort(heap, (short) (instPtr[0] + 1), length); + Util.setShort(heap, (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + 1), length); } } diff --git a/Applet/src/com/android/javacard/keymaster/KMByteTag.java b/Applet/src/com/android/javacard/keymaster/KMByteTag.java index 0ae6f881..dea36dd1 100644 --- a/Applet/src/com/android/javacard/keymaster/KMByteTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMByteTag.java @@ -30,40 +30,38 @@ public class KMByteTag extends KMTag { private static KMByteTag prototype; - private short[] instPtr; // The allowed tag keys of type bool tag private static final short[] tags = { - APPLICATION_ID, - APPLICATION_DATA, - ROOT_OF_TRUST, - UNIQUE_ID, - ATTESTATION_CHALLENGE, - ATTESTATION_APPLICATION_ID, - ATTESTATION_ID_BRAND, - ATTESTATION_ID_DEVICE, - ATTESTATION_ID_PRODUCT, - ATTESTATION_ID_SERIAL, - ATTESTATION_ID_IMEI, - ATTESTATION_ID_MEID, - ATTESTATION_ID_MANUFACTURER, - ATTESTATION_ID_MODEL, - ASSOCIATED_DATA, - NONCE, - CONFIRMATION_TOKEN, - VERIFIED_BOOT_KEY, - VERIFIED_BOOT_HASH + APPLICATION_ID, + APPLICATION_DATA, + ROOT_OF_TRUST, + UNIQUE_ID, + ATTESTATION_CHALLENGE, + ATTESTATION_APPLICATION_ID, + ATTESTATION_ID_BRAND, + ATTESTATION_ID_DEVICE, + ATTESTATION_ID_PRODUCT, + ATTESTATION_ID_SERIAL, + ATTESTATION_ID_IMEI, + ATTESTATION_ID_MEID, + ATTESTATION_ID_MANUFACTURER, + ATTESTATION_ID_MODEL, + ASSOCIATED_DATA, + NONCE, + CONFIRMATION_TOKEN, + VERIFIED_BOOT_KEY, + VERIFIED_BOOT_HASH }; private KMByteTag() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMByteTag proto(short ptr) { if (prototype == null) { prototype = new KMByteTag(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_BYTE_TAG_OFFSET] = ptr; return prototype; } @@ -109,7 +107,7 @@ public static KMByteTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_BYTE_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -117,11 +115,11 @@ public short getTagType() { } public short getValue() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instanceTable[KM_BYTE_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); } public short length() { - short blobPtr = Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); + short blobPtr = Util.getShort(heap, (short) (instanceTable[KM_BYTE_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); return KMByteBlob.cast(blobPtr).length(); } diff --git a/Applet/src/com/android/javacard/keymaster/KMEnum.java b/Applet/src/com/android/javacard/keymaster/KMEnum.java index 3c5e753f..7ea816a5 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnum.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnum.java @@ -29,31 +29,29 @@ public class KMEnum extends KMType { private static KMEnum prototype; - private short[] instPtr; // The allowed enum types. private static short[] types = { - HARDWARE_TYPE, - KEY_FORMAT, - KEY_DERIVATION_FUNCTION, - VERIFIED_BOOT_STATE, - DEVICE_LOCKED, - USER_AUTH_TYPE, - PURPOSE, - ECCURVE + HARDWARE_TYPE, + KEY_FORMAT, + KEY_DERIVATION_FUNCTION, + VERIFIED_BOOT_STATE, + DEVICE_LOCKED, + USER_AUTH_TYPE, + PURPOSE, + ECCURVE }; private static Object[] enums = null; private KMEnum() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMEnum proto(short ptr) { if (prototype == null) { prototype = new KMEnum(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_ENUM_OFFSET] = ptr; return prototype; } @@ -63,7 +61,7 @@ public static short exp() { } public short length() { - return Util.getShort(heap, (short) (instPtr[0] + 1)); + return Util.getShort(heap, (short) (instanceTable[KM_ENUM_OFFSET] + 1)); } public static KMEnum cast(short ptr) { @@ -99,40 +97,40 @@ private static void create() { // The allowed enum values to corresponding enum types in the types array. if (enums == null) { enums = - new Object[]{ - new byte[]{SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX}, - new byte[]{X509, PKCS8, RAW}, - new byte[]{ - DERIVATION_NONE, - RFC5869_SHA256, - ISO18033_2_KDF1_SHA1, - ISO18033_2_KDF1_SHA256, - ISO18033_2_KDF2_SHA1, - ISO18033_2_KDF2_SHA256 - }, - new byte[]{SELF_SIGNED_BOOT, VERIFIED_BOOT, UNVERIFIED_BOOT, FAILED_BOOT}, - new byte[]{DEVICE_LOCKED_TRUE, DEVICE_LOCKED_FALSE}, - new byte[]{USER_AUTH_NONE, PASSWORD, FINGERPRINT, BOTH}, - new byte[]{ENCRYPT, DECRYPT, SIGN, VERIFY, WRAP_KEY, ATTEST_KEY}, - new byte[]{P_224, P_256, P_384, P_521} - }; + new Object[]{ + new byte[]{SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX}, + new byte[]{X509, PKCS8, RAW}, + new byte[]{ + DERIVATION_NONE, + RFC5869_SHA256, + ISO18033_2_KDF1_SHA1, + ISO18033_2_KDF1_SHA256, + ISO18033_2_KDF2_SHA1, + ISO18033_2_KDF2_SHA256 + }, + new byte[]{SELF_SIGNED_BOOT, VERIFIED_BOOT, UNVERIFIED_BOOT, FAILED_BOOT}, + new byte[]{DEVICE_LOCKED_TRUE, DEVICE_LOCKED_FALSE}, + new byte[]{USER_AUTH_NONE, PASSWORD, FINGERPRINT, BOTH}, + new byte[]{ENCRYPT, DECRYPT, SIGN, VERIFY, WRAP_KEY, ATTEST_KEY}, + new byte[]{P_224, P_256, P_384, P_521} + }; } } public void setVal(byte val) { - heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 2)] = val; + heap[(short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)] = val; } public byte getVal() { - return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 2)]; + return heap[(short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)]; } public void setEnumType(short type) { - Util.setShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE), type); + Util.setShort(heap, (short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE), type); } public short getEnumType() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE)); } // isValidTag enumeration keys and values. diff --git a/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java index 43578509..9d1fb559 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java @@ -28,7 +28,6 @@ public class KMEnumArrayTag extends KMTag { private static KMEnumArrayTag prototype; - private short[] instPtr; // The allowed tag keys of enum array type. private static final short[] tags = {PURPOSE, BLOCK_MODE, DIGEST, PADDING}; @@ -37,14 +36,13 @@ public class KMEnumArrayTag extends KMTag { private static Object[] enums = null; private KMEnumArrayTag() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMEnumArrayTag proto(short ptr) { if (prototype == null) { prototype = new KMEnumArrayTag(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_ENUM_ARRAY_TAG_OFFSET] = ptr; return prototype; } @@ -109,7 +107,7 @@ public static KMEnumArrayTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_ENUM_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -117,11 +115,11 @@ public short getTagType() { } public short getValues() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instanceTable[KM_ENUM_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); } public short length() { - short blobPtr = Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); + short blobPtr = Util.getShort(heap, (short) (instanceTable[KM_ENUM_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); return KMByteBlob.cast(blobPtr).length(); } @@ -129,14 +127,14 @@ public static void create() { if (enums == null) { // allowed tag values. enums = - new Object[]{ - new byte[]{ENCRYPT, DECRYPT, SIGN, VERIFY, WRAP_KEY, ATTEST_KEY}, - new byte[]{ECB, CBC, CTR, GCM}, - new byte[]{DIGEST_NONE, MD5, SHA1, SHA2_224, SHA2_256, SHA2_384, SHA2_512}, - new byte[]{ - PADDING_NONE, RSA_OAEP, RSA_PSS, RSA_PKCS1_1_5_ENCRYPT, RSA_PKCS1_1_5_SIGN, PKCS7 - } - }; + new Object[]{ + new byte[]{ENCRYPT, DECRYPT, SIGN, VERIFY, WRAP_KEY, ATTEST_KEY}, + new byte[]{ECB, CBC, CTR, GCM}, + new byte[]{DIGEST_NONE, MD5, SHA1, SHA2_224, SHA2_256, SHA2_384, SHA2_512}, + new byte[]{ + PADDING_NONE, RSA_OAEP, RSA_PSS, RSA_PKCS1_1_5_ENCRYPT, RSA_PKCS1_1_5_SIGN, PKCS7 + } + }; } } @@ -236,10 +234,10 @@ public boolean isValidPaddingModes(byte alg) { switch (alg) { case KMType.RSA: if (padding != KMType.RSA_OAEP - && padding != KMType.PADDING_NONE - && padding != KMType.RSA_PKCS1_1_5_SIGN - && padding != KMType.RSA_PKCS1_1_5_ENCRYPT - && padding != KMType.RSA_PSS) { + && padding != KMType.PADDING_NONE + && padding != KMType.RSA_PKCS1_1_5_SIGN + && padding != KMType.RSA_PKCS1_1_5_ENCRYPT + && padding != KMType.RSA_PSS) { return false; } break; diff --git a/Applet/src/com/android/javacard/keymaster/KMEnumTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumTag.java index a8ff3f36..aa5d673f 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnumTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnumTag.java @@ -29,25 +29,23 @@ public class KMEnumTag extends KMTag { private static KMEnumTag prototype; - private short[] instPtr; // The allowed tag keys of type enum tag. private static short[] tags = { - ALGORITHM, ECCURVE, BLOB_USAGE_REQ, USER_AUTH_TYPE, ORIGIN, HARDWARE_TYPE + ALGORITHM, ECCURVE, BLOB_USAGE_REQ, USER_AUTH_TYPE, ORIGIN, HARDWARE_TYPE }; private static Object[] enums = null; private KMEnumTag() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMEnumTag proto(short ptr) { if (prototype == null) { prototype = new KMEnumTag(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_ENUM_TAG_OFFSET] = ptr; return prototype; } @@ -90,7 +88,7 @@ public static KMEnumTag cast(short ptr) { } public short getKey() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_ENUM_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); } public short getTagType() { @@ -98,22 +96,22 @@ public short getTagType() { } public byte getValue() { - return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 4)]; + return heap[(short) (instanceTable[KM_ENUM_TAG_OFFSET] + TLV_HEADER_SIZE + 4)]; } public static void create() { if (enums == null) { // enum tag values. enums = - new Object[]{ - 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[]{GENERATED, DERIVED, IMPORTED, UNKNOWN, SECURELY_IMPORTED}, - new byte[]{SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX} - }; + new Object[]{ + 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[]{GENERATED, DERIVED, IMPORTED, UNKNOWN, SECURELY_IMPORTED}, + new byte[]{SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX} + }; } } diff --git a/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java b/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java index 8a68be77..d05ccea4 100644 --- a/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java +++ b/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java @@ -38,10 +38,8 @@ public class KMHardwareAuthToken extends KMType { public static final byte MAC = 0x05; private static KMHardwareAuthToken prototype; - private short[] instPtr; private KMHardwareAuthToken() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } public static short exp() { @@ -60,7 +58,7 @@ private static KMHardwareAuthToken proto(short ptr) { if (prototype == null) { prototype = new KMHardwareAuthToken(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_HARDWARE_AUTH_TOKEN_OFFSET] = ptr; return prototype; } @@ -98,7 +96,7 @@ public static KMHardwareAuthToken cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_HARDWARE_AUTH_TOKEN_OFFSET] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java b/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java index b149b8bd..c5ec91ef 100644 --- a/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java +++ b/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java @@ -33,10 +33,8 @@ public class KMHmacSharingParameters extends KMType { public static final byte NONCE = 0x01; private static KMHmacSharingParameters prototype; - private short[] instPtr; private KMHmacSharingParameters() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } public static short exp() { @@ -51,7 +49,7 @@ private static KMHmacSharingParameters proto(short ptr) { if (prototype == null) { prototype = new KMHmacSharingParameters(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_HMAC_SHARING_PARAMETERS_OFFSET] = ptr; return prototype; } @@ -81,7 +79,7 @@ public static KMHmacSharingParameters cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_HMAC_SHARING_PARAMETERS_OFFSET] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMInteger.java b/Applet/src/com/android/javacard/keymaster/KMInteger.java index 997eb637..c120c22a 100644 --- a/Applet/src/com/android/javacard/keymaster/KMInteger.java +++ b/Applet/src/com/android/javacard/keymaster/KMInteger.java @@ -30,17 +30,15 @@ public class KMInteger extends KMType { public static final short UINT_32 = 4; public static final short UINT_64 = 8; private static KMInteger prototype; - private short[] instPtr; private KMInteger() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMInteger proto(short ptr) { if (prototype == null) { prototype = new KMInteger(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_INTEGER_OFFSET] = ptr; return prototype; } @@ -117,7 +115,7 @@ public static short uint_64(byte[] num, short offset) { // Get the length of the integer public short length() { - return Util.getShort(heap, (short) (instPtr[0] + 1)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_OFFSET] + 1)); } // Get the buffer pointer in which blob is contained. @@ -127,7 +125,7 @@ public byte[] getBuffer() { // Get the start of value public short getStartOff() { - return (short) (instPtr[0] + TLV_HEADER_SIZE); + return (short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE); } public void getValue(byte[] dest, short destOff, short length) { @@ -138,28 +136,28 @@ public void getValue(byte[] dest, short destOff, short length) { length = length(); destOff += length; } - Util.arrayCopyNonAtomic(heap, (short) (instPtr[0] + TLV_HEADER_SIZE), dest, destOff, length); + Util.arrayCopyNonAtomic(heap, (short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE), dest, destOff, length); } public void setValue(byte[] src, short srcOff) { - Util.arrayCopyNonAtomic(src, srcOff, heap, (short) (instPtr[0] + TLV_HEADER_SIZE), length()); + Util.arrayCopyNonAtomic(src, srcOff, heap, (short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE), length()); } public short value(byte[] dest, short destOff) { - Util.arrayCopyNonAtomic(heap, (short) (instPtr[0] + TLV_HEADER_SIZE), dest, destOff, length()); + Util.arrayCopyNonAtomic(heap, (short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE), dest, destOff, length()); return length(); } public short getShort() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE + 2)); } public short getSignificantShort() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE)); } public byte getByte() { - return heap[(short) (instPtr[0] + TLV_HEADER_SIZE + 3)]; + return heap[(short) (instanceTable[KM_INTEGER_OFFSET] + TLV_HEADER_SIZE + 3)]; } public boolean isZero() { @@ -179,13 +177,13 @@ public static short compare(short num1, short num2) { len = KMInteger.cast(num2).length(); KMInteger.cast(num2).getValue(repository.getHeap(), (short) (num2Buf + (short) (8 - len)), len); return KMInteger.unsignedByteArrayCompare( - repository.getHeap(), num1Buf, - repository.getHeap(), num2Buf, - (short) 8); + repository.getHeap(), num1Buf, + repository.getHeap(), num2Buf, + (short) 8); } public static byte unsignedByteArrayCompare(byte[] a1, short offset1, byte[] a2, short offset2, - short length) { + short length) { byte count = (byte) 0; short val1 = (short) 0; short val2 = (short) 0; diff --git a/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java index b9e3b3af..c4d01045 100644 --- a/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java @@ -29,19 +29,17 @@ public class KMIntegerArrayTag extends KMTag { private static KMIntegerArrayTag prototype; - private short[] instPtr; private static final short[] tags = {USER_SECURE_ID}; private KMIntegerArrayTag() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMIntegerArrayTag proto(short ptr) { if (prototype == null) { prototype = new KMIntegerArrayTag(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] = ptr; return prototype; } @@ -97,15 +95,15 @@ public static KMIntegerArrayTag cast(short ptr) { } public short getTagType() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE)); } public short getKey() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); } public short getValues() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); } public short length() { @@ -139,7 +137,7 @@ private static boolean validateTagType(short tagType) { public static boolean contains(short tagId, short tagValue, short params) { short tag = - KMKeyParameters.findTag(KMType.UINT_ARRAY_TAG, tagId, params); + KMKeyParameters.findTag(KMType.UINT_ARRAY_TAG, tagId, params); if (tag != KMType.INVALID_VALUE) { short index = 0; tag = KMIntegerArrayTag.cast(tag).getValues(); diff --git a/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java index 5c79635f..67a46d6d 100644 --- a/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java @@ -29,39 +29,37 @@ public class KMIntegerTag extends KMTag { private static KMIntegerTag prototype; - private short[] instPtr; // Allowed tag keys. private static final short[] tags = { - // UINT - KEYSIZE, - MIN_MAC_LENGTH, - MIN_SEC_BETWEEN_OPS, - MAX_USES_PER_BOOT, - USERID, - AUTH_TIMEOUT, - OS_VERSION, - OS_PATCH_LEVEL, - VENDOR_PATCH_LEVEL, - BOOT_PATCH_LEVEL, - MAC_LENGTH, - // ULONG - RSA_PUBLIC_EXPONENT, - // DATE - ACTIVE_DATETIME, - ORIGINATION_EXPIRE_DATETIME, - USAGE_EXPIRE_DATETIME, - CREATION_DATETIME + // UINT + KEYSIZE, + MIN_MAC_LENGTH, + MIN_SEC_BETWEEN_OPS, + MAX_USES_PER_BOOT, + USERID, + AUTH_TIMEOUT, + OS_VERSION, + OS_PATCH_LEVEL, + VENDOR_PATCH_LEVEL, + BOOT_PATCH_LEVEL, + MAC_LENGTH, + // ULONG + RSA_PUBLIC_EXPONENT, + // DATE + ACTIVE_DATETIME, + ORIGINATION_EXPIRE_DATETIME, + USAGE_EXPIRE_DATETIME, + CREATION_DATETIME }; private KMIntegerTag() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMIntegerTag proto(short ptr) { if (prototype == null) { prototype = new KMIntegerTag(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_INTEGER_TAG_OFFSET] = ptr; return prototype; } @@ -117,15 +115,15 @@ public static KMIntegerTag cast(short ptr) { } public short getTagType() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_TAG_OFFSET] + TLV_HEADER_SIZE)); } public short getKey() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 2)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); } public short getValue() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE + 4)); + return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); } public short length() { @@ -162,7 +160,7 @@ public static short getShortValue(short tagType, short tagKey, short keyParamete } public static short getValue( - byte[] buf, short offset, short tagType, short tagKey, short keyParameters) { + byte[] buf, short offset, short tagType, short tagKey, short keyParameters) { short ptr; if ((tagType == UINT_TAG) || (tagType == ULONG_TAG) || (tagType == DATE_TAG)) { ptr = KMKeyParameters.findTag(tagType, tagKey, keyParameters); @@ -175,7 +173,7 @@ public static short getValue( } public boolean isValidKeySize(byte alg) { - short val = KMIntegerTag.cast(instPtr[0]).getValue(); + short val = KMIntegerTag.cast(instanceTable[KM_INTEGER_TAG_OFFSET]).getValue(); if (KMInteger.cast(val).getSignificantShort() != 0) { return false; } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java b/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java index 5ac2ef4d..13bf86bb 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java @@ -32,10 +32,8 @@ public class KMKeyCharacteristics extends KMType { public static final byte SOFTWARE_ENFORCED = 0x00; public static final byte HARDWARE_ENFORCED = 0x01; private static KMKeyCharacteristics prototype; - private short[] instPtr; private KMKeyCharacteristics() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } public static short exp() { @@ -52,7 +50,7 @@ private static KMKeyCharacteristics proto(short ptr) { if (prototype == null) { prototype = new KMKeyCharacteristics(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_KEY_CHARACTERISTICS_OFFSET] = ptr; return prototype; } @@ -82,7 +80,7 @@ public static KMKeyCharacteristics cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_KEY_CHARACTERISTICS_OFFSET] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java index 3c53bb35..5cea10e2 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java @@ -29,17 +29,15 @@ public class KMKeyParameters extends KMType { private static KMKeyParameters prototype; - private short[] instPtr; private KMKeyParameters() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMKeyParameters proto(short ptr) { if (prototype == null) { prototype = new KMKeyParameters(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_KEY_PARAMETERS_OFFSET] = ptr; return prototype; } @@ -76,7 +74,7 @@ public static KMKeyParameters cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_KEY_PARAMETERS_OFFSET] + TLV_HEADER_SIZE)); } public short length() { diff --git a/Applet/src/com/android/javacard/keymaster/KMType.java b/Applet/src/com/android/javacard/keymaster/KMType.java index 59a4b172..f571275c 100644 --- a/Applet/src/com/android/javacard/keymaster/KMType.java +++ b/Applet/src/com/android/javacard/keymaster/KMType.java @@ -18,6 +18,7 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.framework.JCSystem; import javacard.framework.Util; /** @@ -275,11 +276,32 @@ public abstract class KMType { public static final short LENGTH_FROM_PDU = (short) 0xFFFF; public static final byte NO_VALUE = (byte) 0xff; + // Type offsets. + public static final byte KM_TYPE_BASE_OFFSET = 0; + public static final byte KM_ARRAY_OFFSET = KM_TYPE_BASE_OFFSET; + public static final byte KM_BOOL_TAG_OFFSET = KM_TYPE_BASE_OFFSET + 1; + public static final byte KM_BYTE_BLOB_OFFSET = KM_TYPE_BASE_OFFSET + 2; + public static final byte KM_BYTE_TAG_OFFSET = KM_TYPE_BASE_OFFSET + 3; + public static final byte KM_ENUM_OFFSET = KM_TYPE_BASE_OFFSET + 4; + public static final byte KM_ENUM_ARRAY_TAG_OFFSET = KM_TYPE_BASE_OFFSET + 5; + public static final byte KM_ENUM_TAG_OFFSET = KM_TYPE_BASE_OFFSET + 6; + public static final byte KM_HARDWARE_AUTH_TOKEN_OFFSET = KM_TYPE_BASE_OFFSET + 7; + public static final byte KM_HMAC_SHARING_PARAMETERS_OFFSET = KM_TYPE_BASE_OFFSET + 8; + public static final byte KM_INTEGER_OFFSET = KM_TYPE_BASE_OFFSET + 9; + public static final byte KM_INTEGER_ARRAY_TAG_OFFSET = KM_TYPE_BASE_OFFSET + 10; + public static final byte KM_INTEGER_TAG_OFFSET = KM_TYPE_BASE_OFFSET + 11; + public static final byte KM_KEY_CHARACTERISTICS_OFFSET = KM_TYPE_BASE_OFFSET + 12; + public static final byte KM_KEY_PARAMETERS_OFFSET = KM_TYPE_BASE_OFFSET + 13; + public static final byte KM_VERIFICATION_TOKEN_OFFSET = KM_TYPE_BASE_OFFSET + 14; protected static KMRepository repository; protected static byte[] heap; + // Instance table + public static final byte INSTANCE_TABLE_SIZE = 15; + protected static short[] instanceTable; public static void initialize() { + instanceTable = JCSystem.makeTransientShortArray(INSTANCE_TABLE_SIZE, JCSystem.CLEAR_ON_RESET); KMType.repository = KMRepository.instance(); KMType.heap = repository.getHeap(); } diff --git a/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java b/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java index a57ac803..345dc26c 100644 --- a/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java +++ b/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java @@ -37,10 +37,8 @@ public class KMVerificationToken extends KMType { public static final byte MAC = 0x04; private static KMVerificationToken prototype; - private short[] instPtr; private KMVerificationToken() { - instPtr = (short[]) JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_DESELECT); } public static short exp() { @@ -59,7 +57,7 @@ private static KMVerificationToken proto(short ptr) { if (prototype == null) { prototype = new KMVerificationToken(); } - prototype.instPtr[0] = ptr; + instanceTable[KM_VERIFICATION_TOKEN_OFFSET] = ptr; return prototype; } @@ -96,7 +94,7 @@ public static KMVerificationToken cast(short ptr) { } public short getVals() { - return Util.getShort(heap, (short) (instPtr[0] + TLV_HEADER_SIZE)); + return Util.getShort(heap, (short) (instanceTable[KM_VERIFICATION_TOKEN_OFFSET] + TLV_HEADER_SIZE)); } public short length() { From e658892f74789d0ba7dec0f53663654d3faea358 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 25 Mar 2021 11:58:19 +0000 Subject: [PATCH 06/16] Removed unused imports --- Applet/src/com/android/javacard/keymaster/KMArray.java | 1 - Applet/src/com/android/javacard/keymaster/KMBoolTag.java | 1 - Applet/src/com/android/javacard/keymaster/KMByteBlob.java | 1 - Applet/src/com/android/javacard/keymaster/KMByteTag.java | 1 - Applet/src/com/android/javacard/keymaster/KMEnum.java | 1 - Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java | 1 - Applet/src/com/android/javacard/keymaster/KMEnumTag.java | 1 - .../src/com/android/javacard/keymaster/KMHardwareAuthToken.java | 1 - .../com/android/javacard/keymaster/KMHmacSharingParameters.java | 1 - Applet/src/com/android/javacard/keymaster/KMInteger.java | 1 - Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java | 1 - Applet/src/com/android/javacard/keymaster/KMIntegerTag.java | 1 - .../src/com/android/javacard/keymaster/KMKeyCharacteristics.java | 1 - Applet/src/com/android/javacard/keymaster/KMKeyParameters.java | 1 - .../src/com/android/javacard/keymaster/KMVerificationToken.java | 1 - 15 files changed, 15 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMArray.java b/Applet/src/com/android/javacard/keymaster/KMArray.java index b719af9a..bfa09269 100644 --- a/Applet/src/com/android/javacard/keymaster/KMArray.java +++ b/Applet/src/com/android/javacard/keymaster/KMArray.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMBoolTag.java b/Applet/src/com/android/javacard/keymaster/KMBoolTag.java index 04938e39..69619c0d 100644 --- a/Applet/src/com/android/javacard/keymaster/KMBoolTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMBoolTag.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMByteBlob.java b/Applet/src/com/android/javacard/keymaster/KMByteBlob.java index 2207e978..a6f4c529 100644 --- a/Applet/src/com/android/javacard/keymaster/KMByteBlob.java +++ b/Applet/src/com/android/javacard/keymaster/KMByteBlob.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMByteTag.java b/Applet/src/com/android/javacard/keymaster/KMByteTag.java index dea36dd1..89401e4f 100644 --- a/Applet/src/com/android/javacard/keymaster/KMByteTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMByteTag.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMEnum.java b/Applet/src/com/android/javacard/keymaster/KMEnum.java index 7ea816a5..2b55a6ce 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnum.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnum.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java index 9d1fb559..cd3981c4 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMEnumTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumTag.java index aa5d673f..7493aa3d 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEnumTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMEnumTag.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java b/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java index d05ccea4..900e9069 100644 --- a/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java +++ b/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java b/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java index c5ec91ef..f89ac608 100644 --- a/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java +++ b/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMInteger.java b/Applet/src/com/android/javacard/keymaster/KMInteger.java index c120c22a..aee6f9d5 100644 --- a/Applet/src/com/android/javacard/keymaster/KMInteger.java +++ b/Applet/src/com/android/javacard/keymaster/KMInteger.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java index c4d01045..e292c5e6 100644 --- a/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java index 67a46d6d..6ddec4bd 100644 --- a/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java +++ b/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java b/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java index 13bf86bb..7913f6ff 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java index 5cea10e2..0ef85ae4 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java b/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java index 345dc26c..1be88ded 100644 --- a/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java +++ b/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java @@ -18,7 +18,6 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; -import javacard.framework.JCSystem; import javacard.framework.Util; /** From 05035bf0e4e01c2e137748558ce1050fca829aab Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Thu, 25 Mar 2021 20:10:27 +0000 Subject: [PATCH 07/16] Applet should be able to upgrade even if provision is not done. --- .../com/android/javacard/keymaster/KMAndroidSEProvider.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index 5e247259..bec1234c 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -218,6 +218,12 @@ public KMAndroidSEProvider() { //Allocate buffer for certificate chain. if (!isUpgrading()) { certificateChain = new byte[CERT_CHAIN_MAX_SIZE]; + // Initialize attestationKey and preShared key with zeros. + Util.arrayFillNonAtomic(tmpArray, (short) 0, TMP_ARRAY_SIZE, (byte) 0); + // Assuming secret key length of P-256 curve is 32 bytes. + createAttestationKey(tmpArray, (short)0, (short) 32); + // Pre-shared secret key length is 32 bytes. + createPresharedKey(tmpArray, (short)0, (short) KMRepository.SHARED_SECRET_KEY_SIZE); } androidSEProvider = this; } From a0733a3ffa5c00fbe464fdf06ec5418135fd7762 Mon Sep 17 00:00:00 2001 From: BKSSMVenkateswarlu <40534495+BKSSMVenkateswarlu@users.noreply.github.com> Date: Sun, 28 Mar 2021 16:45:53 +0100 Subject: [PATCH 08/16] Updated comment --- .../src/com/android/javacard/keymaster/KMAndroidSEProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index bec1234c..ecec4e5f 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -220,7 +220,7 @@ public KMAndroidSEProvider() { certificateChain = new byte[CERT_CHAIN_MAX_SIZE]; // Initialize attestationKey and preShared key with zeros. Util.arrayFillNonAtomic(tmpArray, (short) 0, TMP_ARRAY_SIZE, (byte) 0); - // Assuming secret key length of P-256 curve is 32 bytes. + // Create attestation key of P-256 curve. createAttestationKey(tmpArray, (short)0, (short) 32); // Pre-shared secret key length is 32 bytes. createPresharedKey(tmpArray, (short)0, (short) KMRepository.SHARED_SECRET_KEY_SIZE); From 29abbe158a4e854735ea567ce665d598dd1e1d2a Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Thu, 8 Apr 2021 17:33:38 +0100 Subject: [PATCH 09/16] Reduced NVM writes inside KMOperationImpl of AndroidSEProvider --- .../keymaster/KMAndroidSEProvider.java | 10 -- .../javacard/keymaster/KMOperationImpl.java | 102 ++++++++++-------- 2 files changed, 55 insertions(+), 57 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index ecec4e5f..49929346 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -993,22 +993,18 @@ public KMOperation initSymmetricOperation(byte purpose, byte alg, opr = getOperationInstanceFromPool(); // Convert macLength to bytes macLength = (short) (macLength / 8); - JCSystem.beginTransaction(); opr.setCipher(cipher); opr.setCipherAlgorithm(alg); opr.setBlockMode(blockMode); opr.setPaddingAlgorithm(padding); opr.setMode(purpose); opr.setMacLength(macLength); - JCSystem.commitTransaction(); break; case KMType.HMAC: Signature signerVerifier = createHmacSignerVerifier(purpose, digest, keyBuf, keyStart, keyLength); opr = getOperationInstanceFromPool(); - JCSystem.beginTransaction(); opr.setSignature(signerVerifier); - JCSystem.commitTransaction(); break; default: CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); @@ -1071,23 +1067,19 @@ public KMOperation initAsymmetricOperation(byte purpose, byte alg, Signature signer = createRsaSigner(digest, padding, privKeyBuf, privKeyStart, privKeyLength, pubModBuf, pubModStart, pubModLength); opr = getOperationInstanceFromPool(); - JCSystem.beginTransaction(); opr.setSignature(signer); opr.setCipherAlgorithm(alg); opr.setPaddingAlgorithm(padding); opr.setMode(purpose); - JCSystem.commitTransaction(); break; case KMType.DECRYPT: Cipher decipher = createRsaDecipher(padding, digest, privKeyBuf, privKeyStart, privKeyLength, pubModBuf, pubModStart, pubModLength); opr = getOperationInstanceFromPool(); - JCSystem.beginTransaction(); opr.setCipher(decipher); opr.setCipherAlgorithm(alg); opr.setPaddingAlgorithm(padding); opr.setMode(purpose); - JCSystem.commitTransaction(); break; default: KMException.throwIt(KMError.UNSUPPORTED_PURPOSE); @@ -1099,9 +1091,7 @@ public KMOperation initAsymmetricOperation(byte purpose, byte alg, Signature signer = createEcSigner(digest, privKeyBuf, privKeyStart, privKeyLength); opr = getOperationInstanceFromPool(); - JCSystem.beginTransaction(); opr.setSignature(signer); - JCSystem.commitTransaction(); break; default: KMException.throwIt(KMError.UNSUPPORTED_PURPOSE); diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index b5ef9026..a0865d97 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -23,89 +23,89 @@ public class KMOperationImpl implements KMOperation { - private Cipher cipher; - private Signature signature; - private short cipherAlg; - private short padding; - private short mode; - private short blockMode; - private short macLength; + private static final short CIPHER_ALG_OFFSET = 0x00; + private static final short PADDING_OFFSET = 0x01; + private static final short OPER_MODE_OFFSET = 0x02; + private static final short BLOCK_MODE_OFFSET = 0x03; + private static final short MAC_LENGTH_OFFSET = 0x04; //This will hold the length of the buffer stored inside the //Java Card after the GCM update operation. - private short aesGcmUpdatedLen; + private static final short AES_GCM_UPDATE_LEN_OFFSET = 0x05; + private short[] parameters; + // Either one of Cipher/Signature instance is stored. + private Object[] operationInst; public KMOperationImpl() { + parameters = JCSystem.makeTransientShortArray((short) 6, JCSystem.CLEAR_ON_RESET); + operationInst = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET); } public short getMode() { - return mode; + return parameters[OPER_MODE_OFFSET]; } public void setMode(short mode) { - this.mode = mode; + parameters[OPER_MODE_OFFSET] = mode; } public short getMacLength() { - return macLength; + return parameters[MAC_LENGTH_OFFSET]; } public void setMacLength(short macLength) { - this.macLength = macLength; + parameters[MAC_LENGTH_OFFSET] = macLength; } public short getPaddingAlgorithm() { - return padding; + return parameters[PADDING_OFFSET]; } public void setPaddingAlgorithm(short alg) { - padding = alg; + parameters[PADDING_OFFSET] = alg; } public void setBlockMode(short mode) { - blockMode = mode; + parameters[BLOCK_MODE_OFFSET] = mode; } public short getBlockMode() { - return blockMode; + return parameters[BLOCK_MODE_OFFSET]; } public short getCipherAlgorithm() { - return cipherAlg; + return parameters[CIPHER_ALG_OFFSET]; } public void setCipherAlgorithm(short cipherAlg) { - this.cipherAlg = cipherAlg; + parameters[CIPHER_ALG_OFFSET] = cipherAlg; } public void setCipher(Cipher cipher) { - this.cipher = cipher; + operationInst[0] = cipher; } public void setSignature(Signature signer) { - this.signature = signer; + operationInst[0] = signer; } private void resetCipher() { - JCSystem.beginTransaction(); - cipher = null; - macLength = 0; - aesGcmUpdatedLen = 0; - blockMode = 0; - mode = 0; - cipherAlg = 0; - JCSystem.commitTransaction(); + operationInst[0] = null; + parameters[MAC_LENGTH_OFFSET] = 0; + parameters[AES_GCM_UPDATE_LEN_OFFSET] = 0; + parameters[BLOCK_MODE_OFFSET] = 0; + parameters[OPER_MODE_OFFSET] = 0; + parameters[CIPHER_ALG_OFFSET] = 0; + parameters[PADDING_OFFSET] = 0; } @Override public short update(byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { - short len = cipher.update(inputDataBuf, inputDataStart, inputDataLength, + short len = ((Cipher) operationInst[0]).update(inputDataBuf, inputDataStart, inputDataLength, outputDataBuf, outputDataStart); - if (cipherAlg == KMType.AES && blockMode == KMType.GCM) { + if (parameters[CIPHER_ALG_OFFSET] == KMType.AES && parameters[BLOCK_MODE_OFFSET] == KMType.GCM) { // Every time Block size data is stored as intermediate result. - JCSystem.beginTransaction(); - aesGcmUpdatedLen += (short) (inputDataLength - len); - JCSystem.commitTransaction(); + parameters[AES_GCM_UPDATE_LEN_OFFSET] += (short) (inputDataLength - len); } return len; } @@ -113,7 +113,7 @@ public short update(byte[] inputDataBuf, short inputDataStart, @Override public short update(byte[] inputDataBuf, short inputDataStart, short inputDataLength) { - signature.update(inputDataBuf, inputDataStart, inputDataLength); + ((Signature) operationInst[0]).update(inputDataBuf, inputDataStart, inputDataLength); return 0; } @@ -121,6 +121,12 @@ public short update(byte[] inputDataBuf, short inputDataStart, public short finish(byte[] inputDataBuf, short inputDataStart, short inputDataLen, byte[] outputDataBuf, short outputDataStart) { byte[] tmpArray = KMAndroidSEProvider.getInstance().tmpArray; + Cipher cipher = (Cipher) operationInst[0]; + short cipherAlg = parameters[CIPHER_ALG_OFFSET]; + short blockMode = parameters[BLOCK_MODE_OFFSET]; + short mode = parameters[OPER_MODE_OFFSET]; + short macLength = parameters[MAC_LENGTH_OFFSET]; + short padding = parameters[PADDING_OFFSET]; short len = 0; try { if (cipherAlg == KMType.AES && blockMode == KMType.GCM) { @@ -201,11 +207,11 @@ public short sign(byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] signBuf, short signStart) { short len = 0; try { - len = signature.sign(inputDataBuf, inputDataStart, inputDataLength, + len = ((Signature) operationInst[0]).sign(inputDataBuf, inputDataStart, inputDataLength, signBuf, signStart); } finally { - KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature); - signature = null; + KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]); + operationInst[0] = null; } return len; } @@ -215,11 +221,11 @@ public boolean verify(byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] signBuf, short signStart, short signLength) { boolean ret = false; try { - ret = signature.verify(inputDataBuf, inputDataStart, inputDataLength, + ret = ((Signature) operationInst[0]).verify(inputDataBuf, inputDataStart, inputDataLength, signBuf, signStart, signLength); } finally { - KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature); - signature = null; + KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]); + operationInst[0] = null; } return ret; } @@ -227,13 +233,15 @@ public boolean verify(byte[] inputDataBuf, short inputDataStart, @Override public void abort() { // do nothing - if (cipher != null) { - KMAndroidSEProvider.getInstance().releaseCipherInstance(cipher); - resetCipher(); - } - if (signature != null) { - KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature); - signature = null; + if (operationInst[0] != null) { + if (parameters[OPER_MODE_OFFSET] == KMType.ENCRYPT || + parameters[OPER_MODE_OFFSET] == KMType.DECRYPT) { + KMAndroidSEProvider.getInstance().releaseCipherInstance((Cipher) operationInst[0]); + resetCipher(); + } else { + KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]); + } + operationInst[0] = null; } KMAndroidSEProvider.getInstance().releaseOperationInstance(this); } From 01149562054de6c706db9070f2e2eb32428215d7 Mon Sep 17 00:00:00 2001 From: bvenkatswarlu Date: Fri, 9 Apr 2021 03:02:29 +0530 Subject: [PATCH 10/16] Fixed compilation errors --- .../com/android/javacard/keymaster/KMOperationImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index a0865d97..831d3ab0 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -248,15 +248,15 @@ public void abort() { @Override public void updateAAD(byte[] dataBuf, short dataStart, short dataLength) { - ((AEADCipher) cipher).updateAAD(dataBuf, dataStart, dataLength); + ((AEADCipher) operationInst[0]).updateAAD(dataBuf, dataStart, dataLength); } @Override public short getAESGCMOutputSize(short dataSize, short macLength) { - if (mode == KMType.ENCRYPT) { - return (short) (aesGcmUpdatedLen + dataSize + macLength); + if (parameters[OPER_MODE_OFFSET] == KMType.ENCRYPT) { + return (short) (parameters[AES_GCM_UPDATE_LEN_OFFSET] + dataSize + macLength); } else { - return (short) (aesGcmUpdatedLen + dataSize - macLength); + return (short) (parameters[AES_GCM_UPDATE_LEN_OFFSET] + dataSize - macLength); } } } From 1f46af80d245455d53523897a5221f54f6b73024 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 8 Apr 2021 22:36:40 +0100 Subject: [PATCH 11/16] Proper indentation for KMOPerationImpl.java source file --- .../javacard/keymaster/KMOperationImpl.java | 65 +++++++++---------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index 831d3ab0..2a20541c 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -36,8 +36,8 @@ public class KMOperationImpl implements KMOperation { private Object[] operationInst; public KMOperationImpl() { - parameters = JCSystem.makeTransientShortArray((short) 6, JCSystem.CLEAR_ON_RESET); - operationInst = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET); + parameters = JCSystem.makeTransientShortArray((short) 6, JCSystem.CLEAR_ON_RESET); + operationInst = JCSystem.makeTransientObjectArray((short) 1, JCSystem.CLEAR_ON_RESET); } public short getMode() { @@ -45,7 +45,7 @@ public short getMode() { } public void setMode(short mode) { - parameters[OPER_MODE_OFFSET] = mode; + parameters[OPER_MODE_OFFSET] = mode; } public short getMacLength() { @@ -53,7 +53,7 @@ public short getMacLength() { } public void setMacLength(short macLength) { - parameters[MAC_LENGTH_OFFSET] = macLength; + parameters[MAC_LENGTH_OFFSET] = macLength; } public short getPaddingAlgorithm() { @@ -61,7 +61,7 @@ public short getPaddingAlgorithm() { } public void setPaddingAlgorithm(short alg) { - parameters[PADDING_OFFSET] = alg; + parameters[PADDING_OFFSET] = alg; } public void setBlockMode(short mode) { @@ -73,7 +73,7 @@ public short getBlockMode() { } public short getCipherAlgorithm() { - return parameters[CIPHER_ALG_OFFSET]; + return parameters[CIPHER_ALG_OFFSET]; } public void setCipherAlgorithm(short cipherAlg) { @@ -85,11 +85,11 @@ public void setCipher(Cipher cipher) { } public void setSignature(Signature signer) { - operationInst[0] = signer; + operationInst[0] = signer; } private void resetCipher() { - operationInst[0] = null; + operationInst[0] = null; parameters[MAC_LENGTH_OFFSET] = 0; parameters[AES_GCM_UPDATE_LEN_OFFSET] = 0; parameters[BLOCK_MODE_OFFSET] = 0; @@ -100,26 +100,26 @@ private void resetCipher() { @Override public short update(byte[] inputDataBuf, short inputDataStart, - short inputDataLength, byte[] outputDataBuf, short outputDataStart) { + short inputDataLength, byte[] outputDataBuf, short outputDataStart) { short len = ((Cipher) operationInst[0]).update(inputDataBuf, inputDataStart, inputDataLength, - outputDataBuf, outputDataStart); + outputDataBuf, outputDataStart); if (parameters[CIPHER_ALG_OFFSET] == KMType.AES && parameters[BLOCK_MODE_OFFSET] == KMType.GCM) { // Every time Block size data is stored as intermediate result. - parameters[AES_GCM_UPDATE_LEN_OFFSET] += (short) (inputDataLength - len); + parameters[AES_GCM_UPDATE_LEN_OFFSET] += (short) (inputDataLength - len); } return len; } @Override public short update(byte[] inputDataBuf, short inputDataStart, - short inputDataLength) { - ((Signature) operationInst[0]).update(inputDataBuf, inputDataStart, inputDataLength); + short inputDataLength) { + ((Signature) operationInst[0]).update(inputDataBuf, inputDataStart, inputDataLength); return 0; } @Override public short finish(byte[] inputDataBuf, short inputDataStart, - short inputDataLen, byte[] outputDataBuf, short outputDataStart) { + short inputDataLen, byte[] outputDataBuf, short outputDataStart) { byte[] tmpArray = KMAndroidSEProvider.getInstance().tmpArray; Cipher cipher = (Cipher) operationInst[0]; short cipherAlg = parameters[CIPHER_ALG_OFFSET]; @@ -134,7 +134,7 @@ public short finish(byte[] inputDataBuf, short inputDataStart, inputDataLen = (short) (inputDataLen - macLength); } } else if ((cipherAlg == KMType.DES || cipherAlg == KMType.AES) && - padding == KMType.PKCS7 && mode == KMType.ENCRYPT) { + padding == KMType.PKCS7 && mode == KMType.ENCRYPT) { byte blkSize = 16; byte paddingBytes; short inputlen = inputDataLen; @@ -154,15 +154,15 @@ public short finish(byte[] inputDataBuf, short inputDataStart, Util.arrayFillNonAtomic(tmpArray, (short) 0, inputlen, paddingBytes); // copy the input data Util.arrayCopyNonAtomic(inputDataBuf, inputDataStart, tmpArray, - (short) 0, inputDataLen); + (short) 0, inputDataLen); inputDataBuf = tmpArray; inputDataLen = inputlen; inputDataStart = 0; } len = cipher.doFinal(inputDataBuf, inputDataStart, inputDataLen, - outputDataBuf, outputDataStart); + outputDataBuf, outputDataStart); if ((cipherAlg == KMType.AES || cipherAlg == KMType.DES) && - padding == KMType.PKCS7 && mode == KMType.DECRYPT) { + padding == KMType.PKCS7 && mode == KMType.DECRYPT) { byte blkSize = 16; if (cipherAlg == KMType.DES) { blkSize = 8; @@ -185,10 +185,10 @@ public short finish(byte[] inputDataBuf, short inputDataStart, } else if (cipherAlg == KMType.AES && blockMode == KMType.GCM) { if (mode == KMType.ENCRYPT) { len += ((AEADCipher) cipher).retrieveTag(outputDataBuf, - (short) (outputDataStart + len), macLength); + (short) (outputDataStart + len), macLength); } else { boolean verified = ((AEADCipher) cipher).verifyTag(inputDataBuf, - (short) (inputDataStart + inputDataLen), macLength, macLength); + (short) (inputDataStart + inputDataLen), macLength, macLength); if (!verified) { KMException.throwIt(KMError.VERIFICATION_FAILED); } @@ -204,11 +204,11 @@ public short finish(byte[] inputDataBuf, short inputDataStart, @Override public short sign(byte[] inputDataBuf, short inputDataStart, - short inputDataLength, byte[] signBuf, short signStart) { + short inputDataLength, byte[] signBuf, short signStart) { short len = 0; try { len = ((Signature) operationInst[0]).sign(inputDataBuf, inputDataStart, inputDataLength, - signBuf, signStart); + signBuf, signStart); } finally { KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]); operationInst[0] = null; @@ -218,11 +218,11 @@ public short sign(byte[] inputDataBuf, short inputDataStart, @Override public boolean verify(byte[] inputDataBuf, short inputDataStart, - short inputDataLength, byte[] signBuf, short signStart, short signLength) { + short inputDataLength, byte[] signBuf, short signStart, short signLength) { boolean ret = false; try { ret = ((Signature) operationInst[0]).verify(inputDataBuf, inputDataStart, inputDataLength, - signBuf, signStart, signLength); + signBuf, signStart, signLength); } finally { KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]); operationInst[0] = null; @@ -232,16 +232,15 @@ public boolean verify(byte[] inputDataBuf, short inputDataStart, @Override public void abort() { - // do nothing if (operationInst[0] != null) { - if (parameters[OPER_MODE_OFFSET] == KMType.ENCRYPT || - parameters[OPER_MODE_OFFSET] == KMType.DECRYPT) { - KMAndroidSEProvider.getInstance().releaseCipherInstance((Cipher) operationInst[0]); - resetCipher(); - } else { - KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]); - } - operationInst[0] = null; + if (parameters[OPER_MODE_OFFSET] == KMType.ENCRYPT || + parameters[OPER_MODE_OFFSET] == KMType.DECRYPT) { + KMAndroidSEProvider.getInstance().releaseCipherInstance((Cipher) operationInst[0]); + resetCipher(); + } else { + KMAndroidSEProvider.getInstance().releaseSignatureInstance((Signature) operationInst[0]); + } + operationInst[0] = null; } KMAndroidSEProvider.getInstance().releaseOperationInstance(this); } From 52e6797604cc26bbd083127b00c61f53d7b78b23 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Fri, 9 Apr 2021 16:20:27 +0100 Subject: [PATCH 12/16] Changed the variable name from dFlag to isDataUpdated. --- .../javacard/keymaster/KMOperationState.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMOperationState.java b/Applet/src/com/android/javacard/keymaster/KMOperationState.java index 333962aa..3fbe47f2 100644 --- a/Applet/src/com/android/javacard/keymaster/KMOperationState.java +++ b/Applet/src/com/android/javacard/keymaster/KMOperationState.java @@ -33,6 +33,8 @@ public class KMOperationState { private static final byte REFS = 1; private static final byte KMOPERATION = 0; private static final byte SLOT = 1; + private static final byte TRUE = 1; + private static final byte FALSE = 0; // byte type private static final byte ALG = 0; private static final byte PURPOSE = 1; @@ -58,12 +60,12 @@ public class KMOperationState { private byte[] data; private Object[] objRefs; private static KMOperationState prototype; - private byte[] dFlag; + private byte[] isDataUpdated; private KMOperationState() { data = JCSystem.makeTransientByteArray(MAX_DATA, JCSystem.CLEAR_ON_RESET); objRefs = JCSystem.makeTransientObjectArray((short) 2, JCSystem.CLEAR_ON_RESET); - dFlag = JCSystem.makeTransientByteArray((short) 1, JCSystem.CLEAR_ON_RESET); + isDataUpdated = JCSystem.makeTransientByteArray((short) 1, JCSystem.CLEAR_ON_RESET); } private static KMOperationState proto() { @@ -93,13 +95,13 @@ public static KMOperationState read(byte[] oprHandle, short off, Object[] slot) } public void persist() { - if (0 == dFlag[0]) { + if (FALSE == isDataUpdated[0]) { return; } KMRepository.instance().persistOperation(data, Util.getShort(data, OP_HANDLE), (KMOperation) objRefs[KMOPERATION]); - dFlag[0] = 0; + isDataUpdated[0] = FALSE; } public void setKeySize(short keySize) { @@ -111,7 +113,7 @@ public short getKeySize() { } public void reset() { - dFlag[0] = 0; + isDataUpdated[0] = FALSE; objRefs[KMOPERATION] = null; objRefs[SLOT] = null; Util.arrayFillNonAtomic( @@ -119,7 +121,7 @@ public void reset() { } private void dataUpdated() { - dFlag[0] = 1; + isDataUpdated[0] = TRUE; } public void release() { From d259d3e9565ff54402d6fea15893e171fe509c2f Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 12 Apr 2021 11:12:15 +0100 Subject: [PATCH 13/16] Memory optimization in operation table. Picked these changes from 43ae1785ac30350519620ee9781bcd5493a5d24f of AvinashHedage master branch. --- .../javacard/keymaster/KMRepository.java | 146 +++++++++--------- 1 file changed, 77 insertions(+), 69 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 07caec72..90350ab1 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -41,7 +41,7 @@ public class KMRepository implements KMUpgradable { private static final short OPERATION_HANDLE_STATUS_SIZE = 1; private static final short OPERATION_HANDLE_OFFSET = 1; private static final short OPERATION_HANDLE_ENTRY_SIZE = - OPERATION_HANDLE_SIZE + OPERATION_HANDLE_STATUS_SIZE; + OPERATION_HANDLE_SIZE + OPERATION_HANDLE_STATUS_SIZE; // Data table offsets public static final byte COMPUTED_HMAC_KEY = 8; @@ -105,15 +105,27 @@ public KMRepository(boolean isUpgrading) { heapIndex[0] = (short) 0; reclaimIndex[0] = HEAP_SIZE; newDataTable(isUpgrading); - operationStateTable = new Object[MAX_OPS]; + operationStateTable = JCSystem.makeTransientObjectArray(MAX_OPS, JCSystem.CLEAR_ON_RESET); // create and initialize operation state table. //First byte in the operation handle buffer denotes whether the operation is //reserved or unreserved. byte index = 0; + Object[] operationStateObj; + Object[] tempObj1; + Object[] tempObj2; + while (index < MAX_OPS) { - operationStateTable[index] = new Object[]{new byte[OPERATION_HANDLE_ENTRY_SIZE], - new Object[]{new byte[KMOperationState.MAX_DATA], - new Object[KMOperationState.MAX_REFS]}}; + operationStateObj = JCSystem.makeTransientObjectArray((short) 2, JCSystem.CLEAR_ON_RESET); + operationStateObj[0] = JCSystem.makeTransientByteArray(OPERATION_HANDLE_ENTRY_SIZE, JCSystem.CLEAR_ON_RESET); + + tempObj1 = JCSystem.makeTransientObjectArray((short) 2, JCSystem.CLEAR_ON_RESET); + tempObj1[0] = JCSystem.makeTransientByteArray(KMOperationState.MAX_DATA, JCSystem.CLEAR_ON_RESET); + + tempObj2 = JCSystem.makeTransientObjectArray(KMOperationState.MAX_REFS, JCSystem.CLEAR_ON_RESET); + tempObj1[1] = tempObj2; + + operationStateObj[1] = tempObj1; + operationStateTable[index] = operationStateObj; index++; } //Initialize the device locked status @@ -138,8 +150,8 @@ public KMOperationState findOperation(byte[] buf, short off, short len) { opId = ((byte[]) ((Object[]) operationStateTable[index])[0]); if (0 == Util.arrayCompare(buf, off, opId, OPERATION_HANDLE_OFFSET, len)) { return KMOperationState - .read(opId, OPERATION_HANDLE_OFFSET, - (Object[]) ((Object[]) operationStateTable[index])[1]); + .read(opId, OPERATION_HANDLE_OFFSET, + (Object[]) ((Object[]) operationStateTable[index])[1]); } index++; } @@ -151,14 +163,14 @@ public KMOperationState findOperation(byte[] buf, short off, short len) { public KMOperationState findOperation(short operationHandle) { short buf = KMByteBlob.instance(OPERATION_HANDLE_SIZE); getOperationHandle( - operationHandle, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + operationHandle, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); return findOperation( - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); } /* opHandle is a KMInteger */ @@ -170,7 +182,7 @@ public KMOperationState reserveOperation(short opHandle) { /* Check for unreserved operation state */ if (opId[OPERATION_HANDLE_STATUS_OFFSET] == 0) { return KMOperationState - .instance(opHandle, (Object[]) ((Object[]) operationStateTable[index])[1]); + .instance(opHandle, (Object[]) ((Object[]) operationStateTable[index])[1]); } index++; } @@ -182,27 +194,25 @@ public void persistOperation(byte[] data, short opHandle, KMOperation op) { byte[] opId; short buf = KMByteBlob.instance(OPERATION_HANDLE_SIZE); getOperationHandle( - opHandle, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + opHandle, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); //Update an existing operation state. while (index < MAX_OPS) { opId = (byte[]) ((Object[]) operationStateTable[index])[0]; if ((1 == opId[OPERATION_HANDLE_STATUS_OFFSET]) - && (0 == Util.arrayCompare( - opId, - OPERATION_HANDLE_OFFSET, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()))) { + && (0 == Util.arrayCompare( + opId, + OPERATION_HANDLE_OFFSET, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()))) { Object[] slot = (Object[]) ((Object[]) operationStateTable[index])[1]; - JCSystem.beginTransaction(); Util.arrayCopy(data, (short) 0, (byte[]) slot[0], (short) 0, - (short) ((byte[]) slot[0]).length); + (short) ((byte[]) slot[0]).length); Object[] ops = ((Object[]) slot[1]); ops[0] = op; - JCSystem.commitTransaction(); return; } index++; @@ -214,19 +224,17 @@ public void persistOperation(byte[] data, short opHandle, KMOperation op) { opId = (byte[]) ((Object[]) operationStateTable[index])[0]; if (0 == opId[OPERATION_HANDLE_STATUS_OFFSET]) { Object[] slot = (Object[]) ((Object[]) operationStateTable[index])[1]; - JCSystem.beginTransaction(); opId[OPERATION_HANDLE_STATUS_OFFSET] = 1;/*reserved */ Util.arrayCopy( - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - opId, - OPERATION_HANDLE_OFFSET, - OPERATION_HANDLE_SIZE); + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + opId, + OPERATION_HANDLE_OFFSET, + OPERATION_HANDLE_SIZE); Util.arrayCopy(data, (short) 0, (byte[]) slot[0], (short) 0, - (short) ((byte[]) slot[0]).length); + (short) ((byte[]) slot[0]).length); Object[] ops = ((Object[]) slot[1]); ops[0] = op; - JCSystem.commitTransaction(); break; } index++; @@ -238,18 +246,18 @@ public void releaseOperation(KMOperationState op) { byte[] oprHandleBuf; short buf = KMByteBlob.instance(OPERATION_HANDLE_SIZE); getOperationHandle( - op.getHandle(), - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + op.getHandle(), + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); while (index < MAX_OPS) { oprHandleBuf = ((byte[]) ((Object[]) operationStateTable[index])[0]); if ((oprHandleBuf[OPERATION_HANDLE_STATUS_OFFSET] == 1) && - (0 == Util.arrayCompare(oprHandleBuf, - OPERATION_HANDLE_OFFSET, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()))) { + (0 == Util.arrayCompare(oprHandleBuf, + OPERATION_HANDLE_OFFSET, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()))) { JCSystem.beginTransaction(); Util.arrayFillNonAtomic(oprHandleBuf, (short) 0, (short) oprHandleBuf.length, (byte) 0); JCSystem.commitTransaction(); @@ -271,7 +279,7 @@ public void releaseAllOperations() { ((KMOperation) ops[0]).abort(); JCSystem.beginTransaction(); Util.arrayFillNonAtomic((byte[]) slot[0], (short) 0, - (short) ((byte[]) slot[0]).length, (byte) 0); + (short) ((byte[]) slot[0]).length, (byte) 0); Util.arrayFillNonAtomic(oprHandleBuf, (short) 0, (short) oprHandleBuf.length, (byte) 0); ops[0] = null; JCSystem.commitTransaction(); @@ -327,7 +335,7 @@ public void onSelect() { // reclaimMemory function immediately after the use. public short allocReclaimableMemory(short length) { if ((((short) (reclaimIndex[0] - length)) <= heapIndex[0]) - || (length >= HEAP_SIZE / 2)) { + || (length >= HEAP_SIZE / 2)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } reclaimIndex[0] -= length; @@ -353,7 +361,7 @@ public short allocAvailableMemory() { public short alloc(short length) { if ((((short) (heapIndex[0] + length)) > heap.length) || - (((short) (heapIndex[0] + length)) > reclaimIndex[0])) { + (((short) (heapIndex[0] + length)) > reclaimIndex[0])) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } heapIndex[0] += length; @@ -381,9 +389,9 @@ private void newDataTable(boolean isUpgrading) { public void restoreData(short blob) { JCSystem.beginTransaction(); Util.arrayCopy( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff(), dataTable, - (short) 0, - KMByteBlob.cast(blob).length() + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff(), dataTable, + (short) 0, + KMByteBlob.cast(blob).length() ); JCSystem.commitTransaction(); } @@ -428,11 +436,11 @@ private short readDataEntry(short id, byte[] buf, short offset) { short len = Util.getShort(dataTable, (short) (id + DATA_INDEX_ENTRY_LENGTH)); if (len != 0) { Util.arrayCopyNonAtomic( - dataTable, - Util.getShort(dataTable, (short) (id + DATA_INDEX_ENTRY_OFFSET)), - buf, - offset, - len); + dataTable, + Util.getShort(dataTable, (short) (id + DATA_INDEX_ENTRY_OFFSET)), + buf, + offset, + len); } return len; } @@ -480,7 +488,7 @@ public short getIssuer() { public short readData(short id) { short blob = KMByteBlob.instance(dataLength(id)); if (readDataEntry(id, KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()) - == 0) { + == 0) { return 0; } return blob; @@ -505,7 +513,7 @@ public short getOsVersion() { short blob = readData(BOOT_OS_VERSION); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -515,7 +523,7 @@ public short getVendorPatchLevel() { short blob = readData(VENDOR_PATCH_LEVEL); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -525,7 +533,7 @@ public short getBootPatchLevel() { short blob = readData(BOOT_PATCH_LEVEL); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -535,7 +543,7 @@ public short getOsPatch() { short blob = readData(BOOT_OS_PATCH); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -563,19 +571,19 @@ public short readROT() { short blob = KMByteBlob.instance(totalLength); length = readDataEntry(BOOT_VERIFIED_BOOT_KEY, KMByteBlob.cast(blob) - .getBuffer(), KMByteBlob.cast(blob).getStartOff()); + .getBuffer(), KMByteBlob.cast(blob).getStartOff()); length += readDataEntry(BOOT_VERIFIED_BOOT_HASH, KMByteBlob.cast(blob) - .getBuffer(), - (short) (KMByteBlob.cast(blob).getStartOff() + length)); + .getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length)); length += readDataEntry(BOOT_VERIFIED_BOOT_STATE, KMByteBlob.cast(blob) - .getBuffer(), - (short) (KMByteBlob.cast(blob).getStartOff() + length)); + .getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length)); readDataEntry(BOOT_DEVICE_LOCKED_STATUS, KMByteBlob.cast(blob) - .getBuffer(), - (short) (KMByteBlob.cast(blob).getStartOff() + length)); + .getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length)); return blob; } @@ -611,7 +619,7 @@ public short getDeviceTimeStamp() { short blob = readData(DEVICE_LOCKED_TIME); if (blob != 0) { return KMInteger.uint_64(KMByteBlob.cast(blob).getBuffer(), - KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_64(zero, (short) 0); } From 7a10baf9b8fd32e289d08d083937e7c7386d4f15 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 12 Apr 2021 11:16:54 +0100 Subject: [PATCH 14/16] Removed begin/commit transaction from not required places --- Applet/src/com/android/javacard/keymaster/KMRepository.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 90350ab1..8dab3df2 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -258,9 +258,7 @@ public void releaseOperation(KMOperationState op) { KMByteBlob.cast(buf).getBuffer(), KMByteBlob.cast(buf).getStartOff(), KMByteBlob.cast(buf).length()))) { - JCSystem.beginTransaction(); Util.arrayFillNonAtomic(oprHandleBuf, (short) 0, (short) oprHandleBuf.length, (byte) 0); - JCSystem.commitTransaction(); op.release(); break; } @@ -277,12 +275,10 @@ public void releaseAllOperations() { Object[] slot = (Object[]) ((Object[]) operationStateTable[index])[1]; Object[] ops = ((Object[]) slot[1]); ((KMOperation) ops[0]).abort(); - JCSystem.beginTransaction(); Util.arrayFillNonAtomic((byte[]) slot[0], (short) 0, (short) ((byte[]) slot[0]).length, (byte) 0); Util.arrayFillNonAtomic(oprHandleBuf, (short) 0, (short) oprHandleBuf.length, (byte) 0); ops[0] = null; - JCSystem.commitTransaction(); } index++; } From 2fcbbd35d6e9b55051b18a128ba156c3b3005188 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Mon, 12 Apr 2021 11:32:28 +0100 Subject: [PATCH 15/16] Lock provision should not depend on setBoot parameters --- .../com/android/javacard/keymaster/KMKeymasterApplet.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 6db348b3..fb1f3947 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -500,10 +500,9 @@ private void generateUniqueOperationHandle(byte[] buf, short offset, short len) private boolean isProvisioningComplete() { if ((0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_KEY)) - && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) - && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) - && (0 != (provisionStatus & PROVISION_STATUS_PRESHARED_SECRET)) - && (0 != (provisionStatus & PROVISION_STATUS_BOOT_PARAM))) { + && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) + && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) + && (0 != (provisionStatus & PROVISION_STATUS_PRESHARED_SECRET))) { return true; } else { return false; From ec25406dd91774b292a1f533641db406ff9f8801 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 13 Apr 2021 19:51:57 +0100 Subject: [PATCH 16/16] Reverted operationStateTable NVM changes --- .../javacard/keymaster/KMKeymasterApplet.java | 7 +- .../javacard/keymaster/KMRepository.java | 150 +++++++++--------- 2 files changed, 77 insertions(+), 80 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index fb1f3947..6db348b3 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -500,9 +500,10 @@ private void generateUniqueOperationHandle(byte[] buf, short offset, short len) private boolean isProvisioningComplete() { if ((0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_KEY)) - && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) - && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) - && (0 != (provisionStatus & PROVISION_STATUS_PRESHARED_SECRET))) { + && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) + && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) + && (0 != (provisionStatus & PROVISION_STATUS_PRESHARED_SECRET)) + && (0 != (provisionStatus & PROVISION_STATUS_BOOT_PARAM))) { return true; } else { return false; diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 8dab3df2..07caec72 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -41,7 +41,7 @@ public class KMRepository implements KMUpgradable { private static final short OPERATION_HANDLE_STATUS_SIZE = 1; private static final short OPERATION_HANDLE_OFFSET = 1; private static final short OPERATION_HANDLE_ENTRY_SIZE = - OPERATION_HANDLE_SIZE + OPERATION_HANDLE_STATUS_SIZE; + OPERATION_HANDLE_SIZE + OPERATION_HANDLE_STATUS_SIZE; // Data table offsets public static final byte COMPUTED_HMAC_KEY = 8; @@ -105,27 +105,15 @@ public KMRepository(boolean isUpgrading) { heapIndex[0] = (short) 0; reclaimIndex[0] = HEAP_SIZE; newDataTable(isUpgrading); - operationStateTable = JCSystem.makeTransientObjectArray(MAX_OPS, JCSystem.CLEAR_ON_RESET); + operationStateTable = new Object[MAX_OPS]; // create and initialize operation state table. //First byte in the operation handle buffer denotes whether the operation is //reserved or unreserved. byte index = 0; - Object[] operationStateObj; - Object[] tempObj1; - Object[] tempObj2; - while (index < MAX_OPS) { - operationStateObj = JCSystem.makeTransientObjectArray((short) 2, JCSystem.CLEAR_ON_RESET); - operationStateObj[0] = JCSystem.makeTransientByteArray(OPERATION_HANDLE_ENTRY_SIZE, JCSystem.CLEAR_ON_RESET); - - tempObj1 = JCSystem.makeTransientObjectArray((short) 2, JCSystem.CLEAR_ON_RESET); - tempObj1[0] = JCSystem.makeTransientByteArray(KMOperationState.MAX_DATA, JCSystem.CLEAR_ON_RESET); - - tempObj2 = JCSystem.makeTransientObjectArray(KMOperationState.MAX_REFS, JCSystem.CLEAR_ON_RESET); - tempObj1[1] = tempObj2; - - operationStateObj[1] = tempObj1; - operationStateTable[index] = operationStateObj; + operationStateTable[index] = new Object[]{new byte[OPERATION_HANDLE_ENTRY_SIZE], + new Object[]{new byte[KMOperationState.MAX_DATA], + new Object[KMOperationState.MAX_REFS]}}; index++; } //Initialize the device locked status @@ -150,8 +138,8 @@ public KMOperationState findOperation(byte[] buf, short off, short len) { opId = ((byte[]) ((Object[]) operationStateTable[index])[0]); if (0 == Util.arrayCompare(buf, off, opId, OPERATION_HANDLE_OFFSET, len)) { return KMOperationState - .read(opId, OPERATION_HANDLE_OFFSET, - (Object[]) ((Object[]) operationStateTable[index])[1]); + .read(opId, OPERATION_HANDLE_OFFSET, + (Object[]) ((Object[]) operationStateTable[index])[1]); } index++; } @@ -163,14 +151,14 @@ public KMOperationState findOperation(byte[] buf, short off, short len) { public KMOperationState findOperation(short operationHandle) { short buf = KMByteBlob.instance(OPERATION_HANDLE_SIZE); getOperationHandle( - operationHandle, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + operationHandle, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); return findOperation( - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); } /* opHandle is a KMInteger */ @@ -182,7 +170,7 @@ public KMOperationState reserveOperation(short opHandle) { /* Check for unreserved operation state */ if (opId[OPERATION_HANDLE_STATUS_OFFSET] == 0) { return KMOperationState - .instance(opHandle, (Object[]) ((Object[]) operationStateTable[index])[1]); + .instance(opHandle, (Object[]) ((Object[]) operationStateTable[index])[1]); } index++; } @@ -194,25 +182,27 @@ public void persistOperation(byte[] data, short opHandle, KMOperation op) { byte[] opId; short buf = KMByteBlob.instance(OPERATION_HANDLE_SIZE); getOperationHandle( - opHandle, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + opHandle, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); //Update an existing operation state. while (index < MAX_OPS) { opId = (byte[]) ((Object[]) operationStateTable[index])[0]; if ((1 == opId[OPERATION_HANDLE_STATUS_OFFSET]) - && (0 == Util.arrayCompare( - opId, - OPERATION_HANDLE_OFFSET, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()))) { + && (0 == Util.arrayCompare( + opId, + OPERATION_HANDLE_OFFSET, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()))) { Object[] slot = (Object[]) ((Object[]) operationStateTable[index])[1]; + JCSystem.beginTransaction(); Util.arrayCopy(data, (short) 0, (byte[]) slot[0], (short) 0, - (short) ((byte[]) slot[0]).length); + (short) ((byte[]) slot[0]).length); Object[] ops = ((Object[]) slot[1]); ops[0] = op; + JCSystem.commitTransaction(); return; } index++; @@ -224,17 +214,19 @@ public void persistOperation(byte[] data, short opHandle, KMOperation op) { opId = (byte[]) ((Object[]) operationStateTable[index])[0]; if (0 == opId[OPERATION_HANDLE_STATUS_OFFSET]) { Object[] slot = (Object[]) ((Object[]) operationStateTable[index])[1]; + JCSystem.beginTransaction(); opId[OPERATION_HANDLE_STATUS_OFFSET] = 1;/*reserved */ Util.arrayCopy( - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - opId, - OPERATION_HANDLE_OFFSET, - OPERATION_HANDLE_SIZE); + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + opId, + OPERATION_HANDLE_OFFSET, + OPERATION_HANDLE_SIZE); Util.arrayCopy(data, (short) 0, (byte[]) slot[0], (short) 0, - (short) ((byte[]) slot[0]).length); + (short) ((byte[]) slot[0]).length); Object[] ops = ((Object[]) slot[1]); ops[0] = op; + JCSystem.commitTransaction(); break; } index++; @@ -246,19 +238,21 @@ public void releaseOperation(KMOperationState op) { byte[] oprHandleBuf; short buf = KMByteBlob.instance(OPERATION_HANDLE_SIZE); getOperationHandle( - op.getHandle(), - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()); + op.getHandle(), + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()); while (index < MAX_OPS) { oprHandleBuf = ((byte[]) ((Object[]) operationStateTable[index])[0]); if ((oprHandleBuf[OPERATION_HANDLE_STATUS_OFFSET] == 1) && - (0 == Util.arrayCompare(oprHandleBuf, - OPERATION_HANDLE_OFFSET, - KMByteBlob.cast(buf).getBuffer(), - KMByteBlob.cast(buf).getStartOff(), - KMByteBlob.cast(buf).length()))) { + (0 == Util.arrayCompare(oprHandleBuf, + OPERATION_HANDLE_OFFSET, + KMByteBlob.cast(buf).getBuffer(), + KMByteBlob.cast(buf).getStartOff(), + KMByteBlob.cast(buf).length()))) { + JCSystem.beginTransaction(); Util.arrayFillNonAtomic(oprHandleBuf, (short) 0, (short) oprHandleBuf.length, (byte) 0); + JCSystem.commitTransaction(); op.release(); break; } @@ -275,10 +269,12 @@ public void releaseAllOperations() { Object[] slot = (Object[]) ((Object[]) operationStateTable[index])[1]; Object[] ops = ((Object[]) slot[1]); ((KMOperation) ops[0]).abort(); + JCSystem.beginTransaction(); Util.arrayFillNonAtomic((byte[]) slot[0], (short) 0, - (short) ((byte[]) slot[0]).length, (byte) 0); + (short) ((byte[]) slot[0]).length, (byte) 0); Util.arrayFillNonAtomic(oprHandleBuf, (short) 0, (short) oprHandleBuf.length, (byte) 0); ops[0] = null; + JCSystem.commitTransaction(); } index++; } @@ -331,7 +327,7 @@ public void onSelect() { // reclaimMemory function immediately after the use. public short allocReclaimableMemory(short length) { if ((((short) (reclaimIndex[0] - length)) <= heapIndex[0]) - || (length >= HEAP_SIZE / 2)) { + || (length >= HEAP_SIZE / 2)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } reclaimIndex[0] -= length; @@ -357,7 +353,7 @@ public short allocAvailableMemory() { public short alloc(short length) { if ((((short) (heapIndex[0] + length)) > heap.length) || - (((short) (heapIndex[0] + length)) > reclaimIndex[0])) { + (((short) (heapIndex[0] + length)) > reclaimIndex[0])) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } heapIndex[0] += length; @@ -385,9 +381,9 @@ private void newDataTable(boolean isUpgrading) { public void restoreData(short blob) { JCSystem.beginTransaction(); Util.arrayCopy( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff(), dataTable, - (short) 0, - KMByteBlob.cast(blob).length() + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff(), dataTable, + (short) 0, + KMByteBlob.cast(blob).length() ); JCSystem.commitTransaction(); } @@ -432,11 +428,11 @@ private short readDataEntry(short id, byte[] buf, short offset) { short len = Util.getShort(dataTable, (short) (id + DATA_INDEX_ENTRY_LENGTH)); if (len != 0) { Util.arrayCopyNonAtomic( - dataTable, - Util.getShort(dataTable, (short) (id + DATA_INDEX_ENTRY_OFFSET)), - buf, - offset, - len); + dataTable, + Util.getShort(dataTable, (short) (id + DATA_INDEX_ENTRY_OFFSET)), + buf, + offset, + len); } return len; } @@ -484,7 +480,7 @@ public short getIssuer() { public short readData(short id) { short blob = KMByteBlob.instance(dataLength(id)); if (readDataEntry(id, KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()) - == 0) { + == 0) { return 0; } return blob; @@ -509,7 +505,7 @@ public short getOsVersion() { short blob = readData(BOOT_OS_VERSION); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -519,7 +515,7 @@ public short getVendorPatchLevel() { short blob = readData(VENDOR_PATCH_LEVEL); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -529,7 +525,7 @@ public short getBootPatchLevel() { short blob = readData(BOOT_PATCH_LEVEL); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -539,7 +535,7 @@ public short getOsPatch() { short blob = readData(BOOT_OS_PATCH); if (blob != 0) { return KMInteger.uint_32( - KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_32(zero, (short) 0); } @@ -567,19 +563,19 @@ public short readROT() { short blob = KMByteBlob.instance(totalLength); length = readDataEntry(BOOT_VERIFIED_BOOT_KEY, KMByteBlob.cast(blob) - .getBuffer(), KMByteBlob.cast(blob).getStartOff()); + .getBuffer(), KMByteBlob.cast(blob).getStartOff()); length += readDataEntry(BOOT_VERIFIED_BOOT_HASH, KMByteBlob.cast(blob) - .getBuffer(), - (short) (KMByteBlob.cast(blob).getStartOff() + length)); + .getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length)); length += readDataEntry(BOOT_VERIFIED_BOOT_STATE, KMByteBlob.cast(blob) - .getBuffer(), - (short) (KMByteBlob.cast(blob).getStartOff() + length)); + .getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length)); readDataEntry(BOOT_DEVICE_LOCKED_STATUS, KMByteBlob.cast(blob) - .getBuffer(), - (short) (KMByteBlob.cast(blob).getStartOff() + length)); + .getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length)); return blob; } @@ -615,7 +611,7 @@ public short getDeviceTimeStamp() { short blob = readData(DEVICE_LOCKED_TIME); if (blob != 0) { return KMInteger.uint_64(KMByteBlob.cast(blob).getBuffer(), - KMByteBlob.cast(blob).getStartOff()); + KMByteBlob.cast(blob).getStartOff()); } else { return KMInteger.uint_64(zero, (short) 0); }