diff options
author | avinashhedage <avinashh@google.com> | 2023-01-24 08:49:35 +0000 |
---|---|---|
committer | Subrahmanyaman <subrahmanyaman@google.com> | 2023-03-06 17:38:40 +0000 |
commit | e78d87ea8d5991c639882eb0a3a50e1d096c3ee0 (patch) | |
tree | 0ab87bad902039013626df033e6ff298979583ee | |
parent | 9ea276d7ad432d10d1dcf4eea898b70642e6b08c (diff) | |
download | libese-e78d87ea8d5991c639882eb0a3a50e1d096c3ee0.tar.gz |
KeyMint200: Fix for ADPU setOutgoing() in T=0 protocol.
Added necessary validation before calling APDU setOutgoin() function in T=0 protocol.
Test: run vts -m VtsAidlKeyMintTarget
Change-Id: I4bd41aa491fc4755a83499953fa98df811a1f2de
2 files changed, 66 insertions, 0 deletions
diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index b356643..7d84099 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -98,6 +98,20 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis } @Override + public void updateApduStatusFlags(short apduIns) { + apduStatusFlags[APDU_INCOMING_AND_RECEIVE_STATUS_INDEX] = 0; + apduStatusFlags[APDU_CASE4_COMMAND_STATUS_INDEX] = 1; + switch (apduIns) { + case INS_GET_PROVISION_STATUS_CMD: + case INS_SE_FACTORY_PROVISIONING_LOCK_CMD: + apduStatusFlags[APDU_CASE4_COMMAND_STATUS_INDEX] = 0; + break; + default: + super.updateApduStatusFlags(apduIns); + } + } + + @Override public void process(APDU apdu) { try { handleDeviceBooted(); @@ -111,6 +125,7 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis if (apduIns == KMType.INVALID_VALUE) { return; } + updateApduStatusFlags(apduIns); if (((KMAndroidSEProvider) seProvider).isPowerReset()) { super.powerReset(); } @@ -409,6 +424,7 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis // required here. byte[] srcBuffer = apdu.getBuffer(); short recvLen = apdu.setIncomingAndReceive(); + apduStatusFlags[APDU_INCOMING_AND_RECEIVE_STATUS_INDEX] = 1; short srcOffset = apdu.getOffsetCdata(); short bufferLength = apdu.getIncomingLength(); short bufferStartOffset = repository.allocReclaimableMemory(bufferLength); diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 427634c..7d101e8 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -298,6 +298,10 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe // will never be used by the base line code in future. private static final byte INS_KM_VENDOR_START_CMD = (byte) 0xCD; private static final byte INS_KM_VENDOR_END_CMD = (byte) 0xFF; + // Index in apduFlagsStatus[] to check if instruction command is case 4 type in the Apdu + protected static final byte APDU_CASE4_COMMAND_STATUS_INDEX = 0; + // Index in apduFlagsStatus[] to check if Apdu setIncomingAndReceive function is called + protected static final byte APDU_INCOMING_AND_RECEIVE_STATUS_INDEX = 1; // The maximum buffer size of combined seed and nonce. private static final byte HMAC_SHARED_PARAM_MAX_SIZE = 64; // Instance of RemotelyProvisionedComponentDevice, used to redirect the rkp commands. @@ -325,6 +329,9 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe // The transportKey is retrieved and stored in this buffer at stage 1) and is later used in // stage 2). protected static byte[] wrappingKey; + // Transient byte array used to store the flags if APDU command type is of case 4 and if + // APDU setIncomingAndReceive() function is called or not. + protected static byte[] apduStatusFlags; /** Registers this applet. */ protected KMKeymasterApplet(KMSEProvider seImpl) { @@ -340,6 +347,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe wrappingKey = JCSystem.makeTransientByteArray((short) (WRAPPING_KEY_SIZE + 1), JCSystem.CLEAR_ON_RESET); resetWrappingKey(); + apduStatusFlags = JCSystem.makeTransientByteArray((short) 2, JCSystem.CLEAR_ON_RESET); opTable = new KMOperationState[MAX_OPERATIONS_COUNT]; short index = 0; while (index < MAX_OPERATIONS_COUNT) { @@ -368,6 +376,16 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe if (((short) (bufferLength + bufferStartOffset)) > ((short) repository.getHeap().length)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } + + /* In T=0 protocol, On a case 4 command, setIncomingAndReceive() must + * be invoked prior to calling setOutgoing(). Otherwise, erroneous + * behavior may result + * */ + if (apduStatusFlags[APDU_CASE4_COMMAND_STATUS_INDEX] == 1 + && apduStatusFlags[APDU_INCOMING_AND_RECEIVE_STATUS_INDEX] == 0 + && APDU.getProtocol() == APDU.PROTOCOL_T0) { + apdu.setIncomingAndReceive(); + } // Send data apdu.setOutgoing(); apdu.setOutgoingLength(bufferLength); @@ -379,6 +397,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe byte[] srcBuffer = apdu.getBuffer(); short recvLen = apdu.setIncomingAndReceive(); short srcOffset = apdu.getOffsetCdata(); + apduStatusFlags[APDU_INCOMING_AND_RECEIVE_STATUS_INDEX] = 1; // TODO add logic to handle the extended length buffer. In this case the memory can be reused // from extended buffer. short bufferLength = apdu.getIncomingLength(); @@ -1325,6 +1344,28 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe } } + public void updateApduStatusFlags(short apduIns) { + switch (apduIns) { + case INS_EXPORT_KEY_CMD: + case INS_DELETE_ALL_KEYS_CMD: + case INS_DESTROY_ATT_IDS_CMD: + case INS_VERIFY_AUTHORIZATION_CMD: + case INS_GET_HMAC_SHARING_PARAM_CMD: + case INS_GET_HW_INFO_CMD: + case INS_EARLY_BOOT_ENDED_CMD: + case INS_GET_ROT_CHALLENGE_CMD: + case INS_GET_ROT_DATA_CMD: + case INS_GET_RKP_HARDWARE_INFO: + case INS_FINISH_SEND_DATA_CMD: + case INS_GET_RESPONSE_CMD: + apduStatusFlags[APDU_CASE4_COMMAND_STATUS_INDEX] = 0; + break; + default: + // By default the instruction is set to case 4 command instruction. + break; + } + } + /** * Processes an incoming APDU and handles it using command objects. * @@ -1768,6 +1809,15 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe Util.setShort(buffer, bufferStartOffset, (short) 0x8400); short bufferLength = (short) (KMRepository.HEAP_SIZE - bufferStartOffset); + /* In T=0 protocol, On a case 4 command, setIncomingAndReceive() must + * be invoked prior to calling setOutgoing(). Otherwise, erroneous + * behavior may result + * */ + if (apduStatusFlags[APDU_CASE4_COMMAND_STATUS_INDEX] == 1 + && apduStatusFlags[APDU_INCOMING_AND_RECEIVE_STATUS_INDEX] == 0 + && APDU.getProtocol() == APDU.PROTOCOL_T0) { + apdu.setIncomingAndReceive(); + } // Send data apdu.setOutgoing(); apdu.setOutgoingLength(bufferLength); |