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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 51 additions & 41 deletions Applet/Applet/src/com/android/javacard/keymaster/KMArray.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,66 +18,76 @@

import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;

public class KMArray extends KMType {
private KMType[] vals;
private short length;
private short startOff;
private static final short ARRAY_HEADER_SIZE = 3;
private static KMArray prototype;
private static short instPtr;

private KMArray() {
init();
private KMArray() {}

private static KMArray proto(short ptr) {
if (prototype == null) prototype = new KMArray();
instPtr = ptr;
return prototype;
}

@Override
public void init() {
vals = null;
startOff = 0;
length = 0;
public static short exp() {
short ptr = instance(ARRAY_TYPE, ARRAY_HEADER_SIZE);
heap[(short)(ptr + TLV_HEADER_SIZE)] = 0;
Util.setShort(heap,(short)(ptr + TLV_HEADER_SIZE + 1),(short)0 );
return ptr;
}

@Override
public short length() {
return length;
public static short exp(byte type) {
short ptr = instance(ARRAY_TYPE, ARRAY_HEADER_SIZE);
heap[(short)(ptr + TLV_HEADER_SIZE)] = type;
Util.setShort(heap,(short)(ptr + TLV_HEADER_SIZE + 1),(short)0 );
return ptr;
}

public static void create(KMArray[] arrayRefTable) {
byte index = 0;
while (index < arrayRefTable.length) {
arrayRefTable[index] = new KMArray();
index++;
}
public static short instance(short length) {
short ptr = KMType.instance(ARRAY_TYPE, (short)(ARRAY_HEADER_SIZE + (length*2)));
heap[(short)(ptr + TLV_HEADER_SIZE)] = 0;
Util.setShort(heap,(short)(ptr + TLV_HEADER_SIZE + 1),length);
return ptr;
}

public static KMArray instance() {
return repository.newArray();
public static short instance(short length, byte type) {
short ptr = instance(length);
heap[(short)(ptr + TLV_HEADER_SIZE)] = type;
return ptr;
}

public static KMArray instance(short length) {
public static KMArray cast(short ptr) {
if (heap[ptr] != ARRAY_TYPE) ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
return proto(ptr);
}

KMArray inst = repository.newArray();
inst.startOff = repository.newTypeArray(length);
inst.vals = repository.getTypeArrayRef();
inst.length = length;
return inst;
public void add(short index, short objPtr) {
short len = length();
if (index >= len) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
Util.setShort(heap, (short) (instPtr + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short)(index*2)), objPtr) ;
}

public KMArray withLength(short length) {
this.length = length;
return this;
public short get(short index) {
short len = length();
if (index >= len) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
return Util.getShort(heap,(short) (instPtr + TLV_HEADER_SIZE + 3 + (short)(index*2)));
}

public KMArray add(short index, KMType val) {
if (index >= length) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
vals[(short) (startOff + index)] = val;
return this;
public byte containedType(){ return heap[(short)(instPtr + TLV_HEADER_SIZE)];}

public short getStartOff() {
return (short) (instPtr + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE);
}

public short length() {
return Util.getShort(heap, (short) (instPtr + TLV_HEADER_SIZE + 1));
}

public KMType get(short index) {
if (index >= length) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
return vals[(short) (startOff + index)];
public byte[] getBuffer() {
return heap;
}
}
69 changes: 33 additions & 36 deletions Applet/Applet/src/com/android/javacard/keymaster/KMBoolTag.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,8 +18,11 @@

import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;

public class KMBoolTag extends KMTag {
private static KMBoolTag prototype;
private static short instPtr;

private static final short[] tags = {
CALLER_NONCE,
Expand All@@ -34,62 +37,53 @@ public class KMBoolTag extends KMTag {
RESET_SINCE_ID_ROTATION
};

// Array of Tag Values.
private short key;
private byte val;
private KMBoolTag() {}

// assignBlob constructor
private KMBoolTag() {
init();
private static KMBoolTag proto(short ptr) {
if (prototype == null) prototype = new KMBoolTag();
instPtr = ptr;
return prototype;
}

@Override
public void init() {
key = 0;
val = 1; // always 1.
// pointer to an empty instance used as expression
public static short exp() {
short ptr = KMType.exp(TAG_TYPE);
Util.setShort(heap, (short)(ptr+1), BOOL_TAG);
return ptr;
}

public static KMBoolTag instance() {
return repository.newBoolTag();
public static short instance(short key) {
if (!validateKey(key)) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
short ptr = KMType.instance(TAG_TYPE, (short)5);
Util.setShort(heap, (short)(ptr+TLV_HEADER_SIZE), BOOL_TAG);
Util.setShort(heap, (short)(ptr+TLV_HEADER_SIZE+2), key);
heap[(short)(ptr+TLV_HEADER_SIZE+4)] = 0x01;
return ptr;
}

public static void create(KMBoolTag[] boolTagRefTable) {
byte index = 0;
while (index < boolTagRefTable.length) {
boolTagRefTable[index] = new KMBoolTag();
index++;
public static KMBoolTag cast(short ptr) {
if (heap[ptr] != TAG_TYPE) ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
if (Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)) != BOOL_TAG) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
return proto(ptr);
}

@Override
public short getKey() {
return key;
}

@Override
public short length() {
return 1;
return Util.getShort(heap, (short)(instPtr+TLV_HEADER_SIZE+2));
}

@Override
public short getTagType() {
return KMType.BOOL_TAG;
}

public byte getVal() {
return val;
}
// create default assignBlob without any value
public static KMBoolTag instance(short key) {
if (!validateKey(key)) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
KMBoolTag tag = repository.newBoolTag();
tag.key = key;
return tag;
return heap[(short)(instPtr+TLV_HEADER_SIZE+4)];
}

// validate the tag key
// isValidTag the tag key
private static boolean validateKey(short key) {
short index = (short) tags.length;
while (--index >= 0) {
Expand All@@ -99,4 +93,7 @@ private static boolean validateKey(short key) {
}
return false;
}
public static short[] getTags(){
return tags;
}
}
116 changes: 53 additions & 63 deletions Applet/Applet/src/com/android/javacard/keymaster/KMByteBlob.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,93 +20,83 @@
import javacard.framework.ISOException;
import javacard.framework.Util;

// Byte val represents contiguous memory buffer.
// Byte blob represents contiguous memory buffer.
public class KMByteBlob extends KMType {
private byte[] val;
private short startOff;
private short length;
private static KMByteBlob prototype;
private static short instPtr;

private KMByteBlob() {
init();
private KMByteBlob() {}

private static KMByteBlob proto(short ptr) {
if (prototype == null) prototype = new KMByteBlob();
instPtr = ptr;
return prototype;
}

@Override
public void init() {
length = 0;
startOff = 0;
val = null;
// pointer to an empty instance used as expression
public static short exp() {
return KMType.exp(BYTE_BLOB_TYPE);
}

@Override
public short length() {
return length;
// return an empty byte blob instance
public static short instance(short length) {
return KMType.instance(BYTE_BLOB_TYPE, length);
}

public static KMByteBlob instance() {
return repository.newByteBlob();
// byte blob from existing buf
public static short instance(byte[] buf, short startOff, short length) {
short ptr = instance(length);
Util.arrayCopyNonAtomic(buf, startOff, heap, (short) (ptr + TLV_HEADER_SIZE), length);
return ptr;
}

// copy the blob
public static KMByteBlob instance(byte[] blob, short startOff, short length) {
if ((length <= 0) || ((short)(startOff+length) > blob.length)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
// cast the ptr to KMByteBlob
public static KMByteBlob cast(short ptr) {
if (heap[ptr] != BYTE_BLOB_TYPE) ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
if (Util.getShort(heap, (short) (ptr + 1)) == INVALID_VALUE) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
KMByteBlob inst = instance(length);
Util.arrayCopyNonAtomic(blob, startOff, inst.val, inst.startOff, inst.length);
return inst;
return proto(ptr);
}

// returns empty blob with given length
public static KMByteBlob instance(short length) {
if (length <= 0) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
KMByteBlob inst = instance();
inst.startOff = repository.newByteArray(length);
inst.val = repository.getByteHeapRef();
inst.length = length;
return inst;
// Add the byte
public void add(short index, byte val) {
short len = length();
if (index >= len) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
heap[(short) (instPtr + TLV_HEADER_SIZE + index)] = val;
}

public static void create(KMByteBlob[] byteBlobRefTable) {
byte index = 0;
while (index < byteBlobRefTable.length) {
byteBlobRefTable[index] = new KMByteBlob();
index++;
}
// Get the byte
public byte get(short index) {
short len = length();
if (index >= len) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
return heap[(short) (instPtr + TLV_HEADER_SIZE + index)];
}

// sets the expected length for prototype byte val.
public KMByteBlob withLength(short len) {
this.length = len;
return this;
// Get the start of blob
public short getStartOff() {
return (short) (instPtr + TLV_HEADER_SIZE);
}

public void add(short index, byte val) {
if (index >= this.length) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
if (this.val == null) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
this.val[(short) (startOff + index)] = val;
// Get the length of the blob
public short length() {
return Util.getShort(heap, (short) (instPtr + 1));
}

public byte get(short index) {
if (index >= this.length) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
if (this.val == null) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
return this.val[(short) (startOff + index)];
// Get the buffer pointer in which blob is contained.
public byte[] getBuffer() {
return heap;
}

public byte[] getVal() {
return val;
public void getValue(byte[] destBuf, short destStart, short destLength){
Util.arrayCopyNonAtomic(heap, getStartOff(), destBuf, destStart, destLength);
}

public short getStartOff() {
return startOff;
public void setValue(byte[] srcBuf, short srcStart, short srcLength){
if(length() > srcLength){
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
Util.arrayCopyNonAtomic(srcBuf, srcStart, heap, getStartOff(), length());
}

}
Loading