diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 6d5acb36..b79cabaa 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -3142,6 +3142,10 @@ private void updateKeyParameters(byte[] ptrArr, short len) { } // This command is executed to set the boot parameters. + // releaseAllOperations has to be called on every boot, so + // it is called from inside setBootParams. Later in future if + // setBootParams is removed, then make sure that releaseAllOperations + // is moved to a place where it is called on every boot. private void processSetBootParamsCmd(APDU apdu) { receiveIncoming(apdu); byte[] scratchPad = apdu.getBuffer(); @@ -3230,6 +3234,9 @@ private void processSetBootParamsCmd(APDU apdu) { repository.clearComputedHmac(); repository.clearHmacNonce(); + //Clear all the operation state. + repository.releaseAllOperations(); + // Hmac is cleared, so generate a new Hmac nonce. seProvider.newRandomNumber(scratchPad, (short) 0, KMRepository.HMAC_SEED_NONCE_SIZE); repository.initHmacNonce(scratchPad, (short) 0, KMRepository.HMAC_SEED_NONCE_SIZE); diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 204fe312..94bde080 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -233,7 +233,7 @@ public void persistOperation(byte[] data, short opHandle, KMOperation op) { public void releaseOperation(KMOperationState op) { short index = 0; - byte[] var; + byte[] oprHandleBuf; short buf = KMByteBlob.instance(OPERATION_HANDLE_SIZE); getOperationHandle( op.getHandle(), @@ -241,14 +241,16 @@ public void releaseOperation(KMOperationState op) { KMByteBlob.cast(buf).getStartOff(), KMByteBlob.cast(buf).length()); while (index < MAX_OPS) { - var = ((byte[]) ((Object[]) operationStateTable[index])[0]); - if ((var[OPERATION_HANDLE_STATUS_OFFSET] == 1) && - (0 == Util.arrayCompare(var, + 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()))) { - Util.arrayFillNonAtomic(var, (short) 0, (short) var.length, (byte) 0); + JCSystem.beginTransaction(); + Util.arrayFillNonAtomic(oprHandleBuf, (short) 0, (short) oprHandleBuf.length, (byte) 0); + JCSystem.commitTransaction(); op.release(); break; } @@ -256,6 +258,26 @@ public void releaseOperation(KMOperationState op) { } } + public void releaseAllOperations() { + short index = 0; + byte[] oprHandleBuf; + while (index < MAX_OPS) { + oprHandleBuf = ((byte[]) ((Object[]) operationStateTable[index])[0]); + if (oprHandleBuf[OPERATION_HANDLE_STATUS_OFFSET] == 1) { + 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++; + } + } + public void initComputedHmac(byte[] key, short start, short len) { if (len != COMPUTED_HMAC_KEY_SIZE) { KMException.throwIt(KMError.INVALID_INPUT_LENGTH);