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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -433,7 +433,7 @@ public boolean storeAuthTag(byte[] data, short offset, short length, byte[] scra
while (index < MAX_BLOB_STORAGE) {
if ((dataLength((short) (index + AUTH_TAG_1)) == 0)
|| isAuthTagSlotAvailable((short) (index + AUTH_TAG_1), scratchPad, scratchPadOff)) {

Util.arrayFillNonAtomic(scratchPad, scratchPadOff, AUTH_TAG_ENTRY_SIZE, (byte)0);
// prepare auth tag buffer
writeAuthTagState(scratchPad, scratchPadOff, (byte) 1);
Util.arrayCopyNonAtomic(data, offset, scratchPad, (short) (scratchPadOff + 1), AUTH_TAG_LENGTH);
Expand DownExpand Up@@ -897,4 +897,4 @@ public short getBootPatchLevel(byte[] buffer, short start) {
return (short) bootPatchLevel.length;
}

}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@
import com.android.javacard.kmdevice.KMRkpDataStore;
import com.android.javacard.kmdevice.KMSEProvider;
import com.android.javacard.kmdevice.KMTextString;
import com.android.javacard.kmdevice.RemotelyProvisionedComponentDevice;

import javacard.framework.APDU;
import javacard.framework.Util;
Expand DownExpand Up@@ -61,7 +62,7 @@ public void processProvisionDeviceUniqueKey(APDU apdu) {
pubKeyLen, privKeyLen);
short bcc = ((KMKeymintDevice) kmDeviceInst).generateBcc(false, scratchPad);
short len = kmDeviceInst.encodeToApduBuffer(bcc, scratchPad, (short) 0,
KMKeymasterDevice.MAX_COSE_BUF_SIZE);
RemotelyProvisionedComponentDevice.MAX_COSE_BUF_SIZE);
rkpDataStore.storeData(KMDataStoreConstants.BOOT_CERT_CHAIN, scratchPad, (short) 0, len);
writeProvisionStatus(PROVISION_STATUS_DEVICE_UNIQUE_KEY);
kmDeviceInst.sendError(apdu, KMError.OK);
Expand Down
10 changes: 9 additions & 1 deletion Applet/src/com/android/javacard/kmdevice/KMArray.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -137,6 +137,10 @@ private short length() {
return Util.getShort(heap, (short) (KMType.instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + 2));
}

private short setLength(short len) {
return Util.setShort(heap, (short) (KMType.instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + 2), len);
}

private byte[] getBuffer() {
return heap;
}
Expand DownExpand Up@@ -170,7 +174,11 @@ public static short getStartOff(short bPtr) {
public static short length(short bPtr) {
return KMArray.cast(bPtr).length();
}


public static short setLength(short bPtr, short len) {
return KMArray.cast(bPtr).setLength(len);
}

public static byte[] getBuffer(short bPtr) {
return KMArray.cast(bPtr).getBuffer();
}
Expand Down
5 changes: 4 additions & 1 deletion Applet/src/com/android/javacard/kmdevice/KMDecoder.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -344,6 +344,7 @@ private short decodeKeyParam(short exp) {
short tagClass;
short allowedType;
short obj;
short arrPos =0;
// For each tag in payload ...
while (index < payloadLength) {
tagFound = false;
Expand All@@ -359,13 +360,14 @@ private short decodeKeyParam(short exp) {
try {
tagFound = true;
obj = decode(tagClass);
KMArray.add(vals, index, obj);
KMArray.add(vals, arrPos++, obj);
break;
}catch(KMException e){
if(KMException.reason() == KMError.INVALID_TAG &&
!ignoreInvalidTags){
KMException.throwIt(KMError.INVALID_TAG);
}
break;
}
}
tagInd++;
Expand All@@ -376,6 +378,7 @@ private short decodeKeyParam(short exp) {
index++;
}
}
KMArray.setLength(vals, arrPos);
return KMKeyParameters.instance(vals);
}

Expand Down
88 changes: 44 additions & 44 deletions Applet/src/com/android/javacard/kmdevice/KMKeymasterDevice.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ public class KMKeymasterDevice {
public static byte[] confirmationToken;
// Subject is a fixed field with only CN= Android Keystore Key - same for all the keys
private static byte[] defaultSubject;
public static final short MAX_COSE_BUF_SIZE = (short) 1024;

// Top 32 commands are reserved for provisioning.
private static final byte KEYMINT_CMD_APDU_START = 0x20;

Expand DownExpand Up@@ -89,7 +89,7 @@ public class KMKeymasterDevice {
private static final byte INS_ABORT_OPERATION_CMD = KEYMINT_CMD_APDU_START + 19; //0x33
private static final byte INS_DEVICE_LOCKED_CMD = KEYMINT_CMD_APDU_START + 20;//0x34
private static final byte INS_EARLY_BOOT_ENDED_CMD = KEYMINT_CMD_APDU_START + 21; //0x35
protected static final byte INS_GET_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 22; //0x36
private static final byte INS_GET_CERT_CHAIN_CMD = KEYMINT_CMD_APDU_START + 22; //0x36
private static final byte INS_UPDATE_AAD_OPERATION_CMD = KEYMINT_CMD_APDU_START + 23; //0x37
private static final byte INS_BEGIN_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 24; //0x38
private static final byte INS_FINISH_IMPORT_WRAPPED_KEY_CMD = KEYMINT_CMD_APDU_START + 25; //0x39
Expand All@@ -108,49 +108,49 @@ public class KMKeymasterDevice {
private static final byte INS_END_KM_CMD = 0x7F;

// Data Dictionary items
public static final byte DATA_ARRAY_SIZE = 40;
public static final byte TMP_VARIABLE_ARRAY_SIZE = 5;

public static final byte KEY_PARAMETERS = 0;
public static final byte KEY_CHARACTERISTICS = 1;
public static final byte HIDDEN_PARAMETERS = 2;
public static final byte HW_PARAMETERS = 3;
public static final byte SW_PARAMETERS = 4;
public static final byte AUTH_DATA = 5;
public static final byte AUTH_TAG = 6;
public static final byte NONCE = 7;
public static final byte KEY_BLOB = 8;
public static final byte AUTH_DATA_LENGTH = 9;
public static final byte SECRET = 10;
public static final byte ROT = 11;
public static final byte DERIVED_KEY = 12;
public static final byte RSA_PUB_EXPONENT = 13;
public static final byte APP_ID = 14;
public static final byte APP_DATA = 15;
public static final byte PUB_KEY = 16;
public static final byte IMPORTED_KEY_BLOB = 17;
public static final byte ORIGIN = 18;
public static final byte NOT_USED = 19;
public static final byte MASKING_KEY = 20;
public static final byte HMAC_SHARING_PARAMS = 21;
public static final byte OP_HANDLE = 22;
public static final byte IV = 23;
public static final byte INPUT_DATA = 24;
public static final byte OUTPUT_DATA = 25;
public static final byte HW_TOKEN = 26;
public static final byte VERIFICATION_TOKEN = 27;
public static final byte SIGNATURE = 28;
public static final byte ATTEST_KEY_BLOB = 29;
public static final byte ATTEST_KEY_PARAMS = 30;
public static final byte ATTEST_KEY_ISSUER = 31;
public static final byte CERTIFICATE = 32;
public static final byte PLAIN_SECRET = 33;
public static final byte TEE_PARAMETERS = 34;
public static final byte SB_PARAMETERS = 35;
public static final byte CONFIRMATION_TOKEN = 36;
private static final byte DATA_ARRAY_SIZE = 40;
private static final byte TMP_VARIABLE_ARRAY_SIZE = 5;

protected static final byte KEY_PARAMETERS = 0;
private static final byte KEY_CHARACTERISTICS = 1;
private static final byte HIDDEN_PARAMETERS = 2;
protected static final byte HW_PARAMETERS = 3;
private static final byte SW_PARAMETERS = 4;
private static final byte AUTH_DATA = 5;
private static final byte AUTH_TAG = 6;
private static final byte NONCE = 7;
private static final byte KEY_BLOB = 8;
private static final byte AUTH_DATA_LENGTH = 9;
protected static final byte SECRET = 10;
private static final byte ROT = 11;
private static final byte DERIVED_KEY = 12;
private static final byte RSA_PUB_EXPONENT = 13;
private static final byte APP_ID = 14;
private static final byte APP_DATA = 15;
private static final byte PUB_KEY = 16;
private static final byte IMPORTED_KEY_BLOB = 17;
private static final byte ORIGIN = 18;
private static final byte NOT_USED = 19;
private static final byte MASKING_KEY = 20;
private static final byte HMAC_SHARING_PARAMS = 21;
private static final byte OP_HANDLE = 22;
private static final byte IV = 23;
protected static final byte INPUT_DATA = 24;
protected static final byte OUTPUT_DATA = 25;
private static final byte HW_TOKEN = 26;
private static final byte VERIFICATION_TOKEN = 27;
private static final byte SIGNATURE = 28;
private static final byte ATTEST_KEY_BLOB = 29;
private static final byte ATTEST_KEY_PARAMS = 30;
private static final byte ATTEST_KEY_ISSUER = 31;
private static final byte CERTIFICATE = 32;
private static final byte PLAIN_SECRET = 33;
private static final byte TEE_PARAMETERS = 34;
private static final byte SB_PARAMETERS = 35;
private static final byte CONFIRMATION_TOKEN = 36;

// AddRngEntropy
protected static final short MAX_SEED_SIZE = 2048;
private static final short MAX_SEED_SIZE = 2048;

// Keyblob constants
public static final byte KEY_BLOB_SECRET = 0;
Expand DownExpand Up@@ -3601,7 +3601,7 @@ private short generateAttestKeyCmd(APDU apdu) {
return receiveIncoming(apdu, generateAttestKeyExp());
}

private void processGetCertChainCmd(APDU apdu) {
protected void processGetCertChainCmd(APDU apdu) {
// Make the response
short certChainLen = storeDataInst.getCertificateDataLength(KMDataStoreConstants.CERTIFICATE_CHAIN);
short int32Ptr = KMInteger.uint_16(KMError.OK);
Expand Down
19 changes: 10 additions & 9 deletions Applet/src/com/android/javacard/kmdevice/KMKeymintDevice.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -389,10 +389,6 @@ public short validateApduHeader(APDU apdu) {
byte[] apduBuffer = apdu.getBuffer();
short P1P2 = Util.getShort(apduBuffer, ISO7816.OFFSET_P1);
byte ins = apduBuffer[ISO7816.OFFSET_INS];
switch (ins) {
case INS_GET_CERT_CHAIN_CMD:
return KMError.UNSUPPORTED_INSTRUCTION;
}
if (P1P2 != KEYMINT_HAL_VERSION) {
return KMError.INVALID_P1P2;
}
Expand DownExpand Up@@ -423,7 +419,7 @@ public short generateBcc(boolean testMode, byte[] scratchPad) {
short coseKey = kmCoseInst.constructCoseKey(KMInteger.uint_8(KMCose.COSE_KEY_TYPE_EC2), KMType.INVALID_VALUE,
KMNInteger.uint_8(KMCose.COSE_ALG_ES256), KMInteger.uint_8(KMCose.COSE_KEY_OP_VERIFY),
KMInteger.uint_8(KMCose.COSE_ECCURVE_256), scratchPad, (short) 0, temp, KMType.INVALID_VALUE, false);
temp = encodeToApduBuffer(coseKey, scratchPad, (short) 0, KMKeymasterDevice.MAX_COSE_BUF_SIZE);
temp = encodeToApduBuffer(coseKey, scratchPad, (short) 0, RemotelyProvisionedComponentDevice.MAX_COSE_BUF_SIZE);
// Construct payload.
short payload = kmCoseInst.constructCoseCertPayload(
KMCosePairTextStringTag.instance(KMInteger.uint_8(KMCose.ISSUER),
Expand All@@ -435,15 +431,15 @@ public short generateBcc(boolean testMode, byte[] scratchPad) {
KMCosePairByteBlobTag.instance(KMNInteger.uint_32(KMCose.KEY_USAGE, (short) 0),
KMByteBlob.instance(KMCose.KEY_USAGE_SIGN, (short) 0, (short) KMCose.KEY_USAGE_SIGN.length)));
// temp temporarily holds the length of encoded cert payload.
temp = encodeToApduBuffer(payload, scratchPad, (short) 0, KMKeymasterDevice.MAX_COSE_BUF_SIZE);
temp = encodeToApduBuffer(payload, scratchPad, (short) 0, RemotelyProvisionedComponentDevice.MAX_COSE_BUF_SIZE);
payload = KMByteBlob.instance(scratchPad, (short) 0, temp);

// protected header
short protectedHeader = kmCoseInst.constructHeaders(KMNInteger.uint_8(KMCose.COSE_ALG_ES256), KMType.INVALID_VALUE,
KMType.INVALID_VALUE, KMType.INVALID_VALUE);
// temp temporarily holds the length of encoded headers.
temp = encodeToApduBuffer(protectedHeader, scratchPad, (short) 0,
KMKeymasterDevice.MAX_COSE_BUF_SIZE);
RemotelyProvisionedComponentDevice.MAX_COSE_BUF_SIZE);
protectedHeader = KMByteBlob.instance(scratchPad, (short) 0, temp);

// unprotected headers.
Expand All@@ -455,7 +451,7 @@ public short generateBcc(boolean testMode, byte[] scratchPad) {
payload);
// temp temporarily holds the length of encoded sign structure.
// Encode cose Sign_Structure.
temp = encodeToApduBuffer(coseSignStructure, scratchPad, (short) 0, KMKeymasterDevice.MAX_COSE_BUF_SIZE);
temp = encodeToApduBuffer(coseSignStructure, scratchPad, (short) 0, RemotelyProvisionedComponentDevice.MAX_COSE_BUF_SIZE);
// do sign
short len = seProvider.ecSign256(deviceUniqueKey, scratchPad, (short) 0, temp, scratchPad, temp);
coseSignStructure = KMByteBlob.instance(scratchPad, temp, len);
Expand DownExpand Up@@ -536,7 +532,7 @@ public short validateCertChain(boolean validateEekRoot, byte expCertAlg,
KMByteBlob.instance((short) 0),
KMArray.get(ptr1, KMCose.COSE_SIGN1_PAYLOAD_OFFSET));
encodedLen = encodeToApduBuffer(signStructure, scratchPad,
keySize, KMKeymasterDevice.MAX_COSE_BUF_SIZE);
keySize, RemotelyProvisionedComponentDevice.MAX_COSE_BUF_SIZE);

if (!seProvider.ecVerify256(scratchPad, (short) 0, keySize, scratchPad, keySize, encodedLen,
KMByteBlob.getBuffer(KMArray.get(ptr1, KMCose.COSE_SIGN1_SIGNATURE_OFFSET)),
Expand All@@ -548,5 +544,10 @@ public short validateCertChain(boolean validateEekRoot, byte expCertAlg,
}
return prevCoseKey;
}

@Override
protected void processGetCertChainCmd(APDU apdu) {
KMException.throwIt(KMError.ATTESTATION_KEYS_NOT_PROVISIONED);
}

}
Loading