From af0de2ff06bf701d77c85485810086d9db11d61b Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Mon, 8 Feb 2021 22:11:47 +0530 Subject: [PATCH 1/5] Added few debug statements Added rsaPkcs1Success test in KMFunctionalTest --- .../javacard/keymaster/KMOperationImpl.java | 12 + .../javacard/test/KMFunctionalTest.java | 222 +++++++++++++++++- .../android/javacard/keymaster/KMError.java | 176 +++++++------- .../javacard/keymaster/KMKeymasterApplet.java | 1 + 4 files changed, 313 insertions(+), 98 deletions(-) diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index 78c01302..8379bfae 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -41,9 +41,21 @@ public short update(byte[] inputDataBuf, short inputDataStart, short inputDataLe signature.update(inputDataBuf,inputDataStart,inputDataLength); return 0; } + + + private static void print(byte[] buf, short start, short length){ + StringBuilder sb = new StringBuilder(); + for(int i = start; i < (start+length); i++){ + sb.append(String.format("%02X", buf[i])) ; + //if((i-start)%16 == 0 && (i-start) != 0) sb.append(String.format("\n")); + } + System.out.println(sb.toString()); + } + @Override public short finish(byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { + print(inputDataBuf, inputDataStart, inputDataLength); return cipher.doFinal(inputDataBuf,inputDataStart,inputDataLength,outputDataBuf,outputDataStart); } diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index 74892031..3b0797ea 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -41,15 +41,26 @@ import com.android.javacard.keymaster.KMRepository; import com.android.javacard.keymaster.KMType; import com.android.javacard.keymaster.KMVerificationToken; +//import com.licel.jcardsim.bouncycastle.crypto.Digest; import com.licel.jcardsim.smartcardio.CardSimulator; import com.licel.jcardsim.utils.AIDUtil; + import javacard.framework.AID; import javacard.framework.Util; +import javacard.security.KeyBuilder; +import javacard.security.KeyPair; +import javacard.security.RSAPrivateKey; +import javacard.security.RSAPublicKey; +import javacard.security.Signature; +import javacardx.crypto.Cipher; import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Arrays; +import java.util.Random; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; + import org.junit.Assert; import org.junit.Test; @@ -2027,6 +2038,159 @@ public void testSignWithRsaNonePkcs1(){ cleanUp(); } + public byte[] EncryptMessage(byte[] input, short params, byte[] keyBlob) { + short ret = begin(KMType.ENCRYPT, + KMByteBlob.instance(keyBlob, (short) 0, (short) keyBlob.length), + KMKeyParameters.instance(params), (short) 0); + // Get the operation handle. + short opHandle = KMArray.cast(ret).get((short) 2); + byte[] opHandleBuf = new byte[KMRepository.OPERATION_HANDLE_SIZE]; + KMInteger.cast(opHandle).getValue(opHandleBuf, (short) 0, + (short) opHandleBuf.length); + opHandle = KMInteger.uint_64(opHandleBuf, (short) 0); + + ret = finish(opHandle, + KMByteBlob.instance(input, (short) 0, (short) input.length), null, + (short) 0, (short) 0, (short) 0, KMError.OK); + short dataPtr = KMArray.cast(ret).get((short) 2); + byte[] output = new byte[KMByteBlob.cast(dataPtr).length()]; + if (KMByteBlob.cast(dataPtr).length() > 0) { + Util.arrayCopyNonAtomic(KMByteBlob.cast(dataPtr).getBuffer(), KMByteBlob + .cast(dataPtr).getStartOff(), output, (short) 0, + KMByteBlob.cast(dataPtr).length()); + } + return output; + } + + public byte[] DecryptMessage(byte[] input, short params, byte[] keyBlob) { + short ret = begin(KMType.DECRYPT, + KMByteBlob.instance(keyBlob, (short) 0, (short) keyBlob.length), + KMKeyParameters.instance(params), (short) 0); + // Get the operation handle. + short opHandle = KMArray.cast(ret).get((short) 2); + byte[] opHandleBuf = new byte[KMRepository.OPERATION_HANDLE_SIZE]; + KMInteger.cast(opHandle).getValue(opHandleBuf, (short) 0, + (short) opHandleBuf.length); + opHandle = KMInteger.uint_64(opHandleBuf, (short) 0); + + ret = finish(opHandle, + KMByteBlob.instance(input, (short) 0, (short) input.length), null, + (short) 0, (short) 0, (short) 0, KMError.OK); + short dataPtr = KMArray.cast(ret).get((short) 2); + byte[] output = new byte[KMByteBlob.cast(dataPtr).length()]; + if (KMByteBlob.cast(dataPtr).length() > 0) { + Util.arrayCopyNonAtomic(KMByteBlob.cast(dataPtr).getBuffer(), KMByteBlob + .cast(dataPtr).getStartOff(), output, (short) 0, + KMByteBlob.cast(dataPtr).length()); + } + return output; + } + + public short generateRandom(short upperBound) { + Random rand = new Random(); + short int_random = (short) rand.nextInt(upperBound); + return int_random; + } + + @Test + public void JCardTestRsaPkcs1() { + //Testing with Only Javacard APIs + byte[] message = { + 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, + 0x21 }; + for (int i = 0; i < 500; i++) { + byte[] out = new byte[256]; + byte[] dplain = new byte[256]; + KeyPair rsaKey = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048); + rsaKey.genKeyPair(); + Cipher rsaCipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false); + RSAPublicKey key = (RSAPublicKey) rsaKey.getPublic(); + rsaCipher.init(key, Cipher.MODE_ENCRYPT); + + short outlen = rsaCipher.doFinal(message, (short) 0, + (short) message.length, out, (short) 0); + Assert.assertEquals(outlen, 256); + + RSAPrivateKey privKey = (RSAPrivateKey) rsaKey.getPrivate(); + rsaCipher.init(privKey, Cipher.MODE_DECRYPT); + short d_outlen = rsaCipher.doFinal(out, (short) 0, outlen, dplain, + (short) 0); + Assert.assertEquals(d_outlen, message.length); + byte[] plain = new byte[d_outlen]; + Util.arrayCopyNonAtomic(dplain, (short) 0, plain, (short) 0, d_outlen); + + Assert.assertTrue(Arrays.equals(message, plain)); + } + } + + @Test + public void testVtsRsaPkcs1Success() { + init(); + byte[] message = { + 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, + 0x21 }; // "Hello World!"; + for (int i = 0; i < 250; i++) { + short key = generateRsaKey(null, null); + short rsaKeyPtr = KMArray.cast(key).get((short) 1); + byte[] keyBlob = new byte[KMByteBlob.cast(rsaKeyPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(rsaKeyPtr).getBuffer(), + KMByteBlob.cast(rsaKeyPtr).getStartOff(), keyBlob, (short) 0, + (short) keyBlob.length); + short pkcs1Params = getRsaParams(KMType.DIGEST_NONE, + KMType.RSA_PKCS1_1_5_ENCRYPT); + + byte[] cipherText1 = EncryptMessage(message, pkcs1Params, keyBlob); + Assert.assertEquals((2048 / 8), cipherText1.length); + + pkcs1Params = getRsaParams(KMType.DIGEST_NONE, + KMType.RSA_PKCS1_1_5_ENCRYPT); + byte[] cipherText2 = EncryptMessage(message, pkcs1Params, keyBlob); + Assert.assertEquals((2048 / 8), cipherText2.length); + System.out.println("stage-2"); + // PKCS1 v1.5 randomizes padding so every result should be different. + Assert.assertFalse(Arrays.equals(cipherText1, cipherText2)); + + print(cipherText1, (short) 0, (short) cipherText1.length); + pkcs1Params = getRsaParams(KMType.DIGEST_NONE, + KMType.RSA_PKCS1_1_5_ENCRYPT); + byte[] plainText = DecryptMessage(cipherText1, pkcs1Params, keyBlob); + Assert.assertTrue(Arrays.equals(message, plainText)); + + // Decrypting corrupted ciphertext should fail. + short offset_to_corrupt = generateRandom((short) cipherText1.length); + + byte corrupt_byte; + do { + corrupt_byte = (byte) generateRandom((short) 256); + } while (corrupt_byte == cipherText1[offset_to_corrupt]); + cipherText1[offset_to_corrupt] = corrupt_byte; + + pkcs1Params = getRsaParams(KMType.DIGEST_NONE, + KMType.RSA_PKCS1_1_5_ENCRYPT); + // Do Begin operation. + short ret = begin(KMType.DECRYPT, + KMByteBlob.instance(keyBlob, (short) 0, (short) keyBlob.length), + KMKeyParameters.instance(pkcs1Params), (short) 0); + System.out.println("stage-4"); + + // Get the operation handle. + short opHandle = KMArray.cast(ret).get((short) 2); + byte[] opHandleBuf = new byte[KMRepository.OPERATION_HANDLE_SIZE]; + KMInteger.cast(opHandle).getValue(opHandleBuf, (short) 0, + (short) opHandleBuf.length); + opHandle = KMInteger.uint_64(opHandleBuf, (short) 0); + System.out.println("stage-5"); + short dataPtr = KMByteBlob.instance(cipherText1, (short) 0, + (short) cipherText1.length); + // Finish should return UNKNOWN_ERROR. + ret = finish(opHandle, dataPtr, null, (short) 0, (short) 0, (short) 0, + KMError.UNKNOWN_ERROR); + System.out.println("stage-6"); + System.out.println("Count of i:" + i); + } + cleanUp(); + } + @Test public void testSignVerifyWithHmacSHA256WithUpdate(){ init(); @@ -2560,9 +2724,9 @@ public short processMessage( opHandle = KMInteger.uint_64(opHandleBuf, (short) 0); if (keyPurpose == KMType.VERIFY) { - ret = finish(opHandle, dataPtr, signature, (short) 0, (short) 0, (short) 0); + ret = finish(opHandle, dataPtr, signature, (short) 0, (short) 0, (short) 0, KMError.OK); } else { - ret = finish(opHandle, dataPtr, null, (short) 0, (short) 0, (short) 0); + ret = finish(opHandle, dataPtr, null, (short) 0, (short) 0, (short) 0, KMError.OK); } if(len >0){ dataPtr = KMArray.cast(ret).get((short)2); @@ -2610,7 +2774,34 @@ public short begin(byte keyPurpose, short keyBlob, short keyParmas, short hwToke } } - public short finish(short operationHandle, short data, byte[] signature, short inParams, short hwToken, short verToken) { + public short translateExtendedErrorCodes(short err) { + switch (err) { + case KMError.SW_CONDITIONS_NOT_SATISFIED: + case KMError.UNSUPPORTED_CLA: + case KMError.INVALID_P1P2: + case KMError.INVALID_DATA: + case KMError.CRYPTO_ILLEGAL_USE: + case KMError.CRYPTO_ILLEGAL_VALUE: + case KMError.CRYPTO_INVALID_INIT: + case KMError.CRYPTO_UNINITIALIZED_KEY: + case KMError.GENERIC_UNKNOWN_ERROR: + err = KMError.UNKNOWN_ERROR; + break; + case KMError.CRYPTO_NO_SUCH_ALGORITHM: + err = KMError.UNSUPPORTED_ALGORITHM; + break; + case KMError.UNSUPPORTED_INSTRUCTION: + case KMError.CMD_NOT_ALLOWED: + case KMError.SW_WRONG_LENGTH: + err = KMError.UNIMPLEMENTED; + break; + default: + break; + } + return err; + } + + public short finish(short operationHandle, short data, byte[] signature, short inParams, short hwToken, short verToken, short expectedErr) { if(hwToken == 0) { hwToken = KMHardwareAuthToken.instance(); } @@ -2637,16 +2828,27 @@ public short finish(short operationHandle, short data, byte[] signature, short i CommandAPDU apdu = encodeApdu((byte)INS_FINISH_OPERATION_CMD, arrPtr); // print(commandAPDU.getBytes()); ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - short outParams = KMKeyParameters.exp(); - KMArray.cast(ret).add((short)0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, outParams); - KMArray.cast(ret).add((short)2, KMByteBlob.exp()); byte[] respBuf = response.getBytes(); short len = (short) respBuf.length; + short ret; + short error; + if (expectedErr == KMError.OK) { + ret = KMArray.instance((short) 3); + short outParams = KMKeyParameters.exp(); + KMArray.cast(ret).add((short)0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, outParams); + KMArray.cast(ret).add((short)2, KMByteBlob.exp()); + } else { + ret = KMInteger.exp(); + } ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); + if (expectedErr == KMError.OK) { + error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + } else { + error = KMInteger.cast(ret).getShort(); + error = translateExtendedErrorCodes(error); + } + Assert.assertEquals(error, expectedErr); return ret; } public short update(short operationHandle, short data, short inParams, short hwToken, short verToken) { diff --git a/Applet/src/com/android/javacard/keymaster/KMError.java b/Applet/src/com/android/javacard/keymaster/KMError.java index 8f842236..83eb8c7c 100644 --- a/Applet/src/com/android/javacard/keymaster/KMError.java +++ b/Applet/src/com/android/javacard/keymaster/KMError.java @@ -20,100 +20,100 @@ * positive unlike negative values in keymaster hal. */ public class KMError { - public static short OK = 0; - public static short ROOT_OF_TRUST_ALREADY_SET = 1; - public static short UNSUPPORTED_PURPOSE = 2; - public static short INCOMPATIBLE_PURPOSE = 3; - public static short UNSUPPORTED_ALGORITHM = 4; - public static short INCOMPATIBLE_ALGORITHM = 5; - public static short UNSUPPORTED_KEY_SIZE = 6; - public static short UNSUPPORTED_BLOCK_MODE = 7; - public static short INCOMPATIBLE_BLOCK_MODE = 8; - public static short UNSUPPORTED_MAC_LENGTH = 9; - public static short UNSUPPORTED_PADDING_MODE = 10; - public static short INCOMPATIBLE_PADDING_MODE = 11; - public static short UNSUPPORTED_DIGEST = 12; - public static short INCOMPATIBLE_DIGEST = 13; - public static short INVALID_EXPIRATION_TIME = 14; - public static short INVALID_USER_ID = 15; - public static short INVALID_AUTHORIZATION_TIMEOUT = 16; - public static short UNSUPPORTED_KEY_FORMAT = 17; - public static short INCOMPATIBLE_KEY_FORMAT = 18; - public static short UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = 19; + public static final short OK = 0; + public static final short ROOT_OF_TRUST_ALREADY_SET = 1; + public static final short UNSUPPORTED_PURPOSE = 2; + public static final short INCOMPATIBLE_PURPOSE = 3; + public static final short UNSUPPORTED_ALGORITHM = 4; + public static final short INCOMPATIBLE_ALGORITHM = 5; + public static final short UNSUPPORTED_KEY_SIZE = 6; + public static final short UNSUPPORTED_BLOCK_MODE = 7; + public static final short INCOMPATIBLE_BLOCK_MODE = 8; + public static final short UNSUPPORTED_MAC_LENGTH = 9; + public static final short UNSUPPORTED_PADDING_MODE = 10; + public static final short INCOMPATIBLE_PADDING_MODE = 11; + public static final short UNSUPPORTED_DIGEST = 12; + public static final short INCOMPATIBLE_DIGEST = 13; + public static final short INVALID_EXPIRATION_TIME = 14; + public static final short INVALID_USER_ID = 15; + public static final short INVALID_AUTHORIZATION_TIMEOUT = 16; + public static final short UNSUPPORTED_KEY_FORMAT = 17; + public static final short INCOMPATIBLE_KEY_FORMAT = 18; + public static final short UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = 19; /** For PKCS8 & PKCS12 */ - public static short UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = 20; + public static final short UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = 20; /** For PKCS8 & PKCS12 */ - public static short INVALID_INPUT_LENGTH = 21; + public static final short INVALID_INPUT_LENGTH = 21; - public static short KEY_EXPORT_OPTIONS_INVALID = 22; - public static short DELEGATION_NOT_ALLOWED = 23; - public static short KEY_NOT_YET_VALID = 24; - public static short KEY_EXPIRED = 25; - public static short KEY_USER_NOT_AUTHENTICATED = 26; - public static short OUTPUT_PARAMETER_NULL = 27; - public static short INVALID_OPERATION_HANDLE = 28; - public static short INSUFFICIENT_BUFFER_SPACE = 29; - public static short VERIFICATION_FAILED = 30; - public static short TOO_MANY_OPERATIONS = 31; - public static short UNEXPECTED_NULL_POINTER = 32; - public static short INVALID_KEY_BLOB = 33; - public static short IMPORTED_KEY_NOT_ENCRYPTED = 34; - public static short IMPORTED_KEY_DECRYPTION_FAILED = 35; - public static short IMPORTED_KEY_NOT_SIGNED = 36; - public static short IMPORTED_KEY_VERIFICATION_FAILED = 37; - public static short INVALID_ARGUMENT = 38; - public static short UNSUPPORTED_TAG = 39; - public static short INVALID_TAG = 40; - public static short MEMORY_ALLOCATION_FAILED = 41; - public static short IMPORT_PARAMETER_MISMATCH = 44; - public static short SECURE_HW_ACCESS_DENIED = 45; - public static short OPERATION_CANCELLED = 46; - public static short CONCURRENT_ACCESS_CONFLICT = 47; - public static short SECURE_HW_BUSY = 48; - public static short SECURE_HW_COMMUNICATION_FAILED = 49; - public static short UNSUPPORTED_EC_FIELD = 50; - public static short MISSING_NONCE = 51; - public static short INVALID_NONCE = 52; - public static short MISSING_MAC_LENGTH = 53; - public static short KEY_RATE_LIMIT_EXCEEDED = 54; - public static short CALLER_NONCE_PROHIBITED = 55; - public static short KEY_MAX_OPS_EXCEEDED = 56; - public static short INVALID_MAC_LENGTH = 57; - public static short MISSING_MIN_MAC_LENGTH = 58; - public static short UNSUPPORTED_MIN_MAC_LENGTH = 59; - public static short UNSUPPORTED_KDF = 60; - public static short UNSUPPORTED_EC_CURVE = 61; - public static short KEY_REQUIRES_UPGRADE = 62; - public static short ATTESTATION_CHALLENGE_MISSING = 63; - public static short KEYMASTER_NOT_CONFIGURED = 64; - public static short ATTESTATION_APPLICATION_ID_MISSING = 65; - public static short CANNOT_ATTEST_IDS = 66; - public static short ROLLBACK_RESISTANCE_UNAVAILABLE = 67; - public static short HARDWARE_TYPE_UNAVAILABLE = 68; - public static short PROOF_OF_PRESENCE_REQUIRED = 69; - public static short CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = 70; - public static short NO_USER_CONFIRMATION = 71; - public static short DEVICE_LOCKED = 72; - public static short EARLY_BOOT_ENDED = 73; - public static short UNIMPLEMENTED = 100; - public static short VERSION_MISMATCH = 101; - public static short UNKNOWN_ERROR = 1000; + public static final short KEY_EXPORT_OPTIONS_INVALID = 22; + public static final short DELEGATION_NOT_ALLOWED = 23; + public static final short KEY_NOT_YET_VALID = 24; + public static final short KEY_EXPIRED = 25; + public static final short KEY_USER_NOT_AUTHENTICATED = 26; + public static final short OUTPUT_PARAMETER_NULL = 27; + public static final short INVALID_OPERATION_HANDLE = 28; + public static final short INSUFFICIENT_BUFFER_SPACE = 29; + public static final short VERIFICATION_FAILED = 30; + public static final short TOO_MANY_OPERATIONS = 31; + public static final short UNEXPECTED_NULL_POINTER = 32; + public static final short INVALID_KEY_BLOB = 33; + public static final short IMPORTED_KEY_NOT_ENCRYPTED = 34; + public static final short IMPORTED_KEY_DECRYPTION_FAILED = 35; + public static final short IMPORTED_KEY_NOT_SIGNED = 36; + public static final short IMPORTED_KEY_VERIFICATION_FAILED = 37; + public static final short INVALID_ARGUMENT = 38; + public static final short UNSUPPORTED_TAG = 39; + public static final short INVALID_TAG = 40; + public static final short MEMORY_ALLOCATION_FAILED = 41; + public static final short IMPORT_PARAMETER_MISMATCH = 44; + public static final short SECURE_HW_ACCESS_DENIED = 45; + public static final short OPERATION_CANCELLED = 46; + public static final short CONCURRENT_ACCESS_CONFLICT = 47; + public static final short SECURE_HW_BUSY = 48; + public static final short SECURE_HW_COMMUNICATION_FAILED = 49; + public static final short UNSUPPORTED_EC_FIELD = 50; + public static final short MISSING_NONCE = 51; + public static final short INVALID_NONCE = 52; + public static final short MISSING_MAC_LENGTH = 53; + public static final short KEY_RATE_LIMIT_EXCEEDED = 54; + public static final short CALLER_NONCE_PROHIBITED = 55; + public static final short KEY_MAX_OPS_EXCEEDED = 56; + public static final short INVALID_MAC_LENGTH = 57; + public static final short MISSING_MIN_MAC_LENGTH = 58; + public static final short UNSUPPORTED_MIN_MAC_LENGTH = 59; + public static final short UNSUPPORTED_KDF = 60; + public static final short UNSUPPORTED_EC_CURVE = 61; + public static final short KEY_REQUIRES_UPGRADE = 62; + public static final short ATTESTATION_CHALLENGE_MISSING = 63; + public static final short KEYMASTER_NOT_CONFIGURED = 64; + public static final short ATTESTATION_APPLICATION_ID_MISSING = 65; + public static final short CANNOT_ATTEST_IDS = 66; + public static final short ROLLBACK_RESISTANCE_UNAVAILABLE = 67; + public static final short HARDWARE_TYPE_UNAVAILABLE = 68; + public static final short PROOF_OF_PRESENCE_REQUIRED = 69; + public static final short CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = 70; + public static final short NO_USER_CONFIRMATION = 71; + public static final short DEVICE_LOCKED = 72; + public static final short EARLY_BOOT_ENDED = 73; + public static final short UNIMPLEMENTED = 100; + public static final short VERSION_MISMATCH = 101; + public static final short UNKNOWN_ERROR = 1000; //Extended errors - public static short SW_CONDITIONS_NOT_SATISFIED = 10001; - public static short UNSUPPORTED_CLA = 10002; - public static short INVALID_P1P2 = 10003; - public static short UNSUPPORTED_INSTRUCTION = 10004; - public static short CMD_NOT_ALLOWED = 10005; - public static short SW_WRONG_LENGTH = 10006; - public static short INVALID_DATA = 10007; + public static final short SW_CONDITIONS_NOT_SATISFIED = 10001; + public static final short UNSUPPORTED_CLA = 10002; + public static final short INVALID_P1P2 = 10003; + public static final short UNSUPPORTED_INSTRUCTION = 10004; + public static final short CMD_NOT_ALLOWED = 10005; + public static final short SW_WRONG_LENGTH = 10006; + public static final short INVALID_DATA = 10007; //Crypto errors - public static short CRYPTO_ILLEGAL_USE = 10008; - public static short CRYPTO_ILLEGAL_VALUE = 10009; - public static short CRYPTO_INVALID_INIT = 10010; - public static short CRYPTO_NO_SUCH_ALGORITHM = 10011; - public static short CRYPTO_UNINITIALIZED_KEY = 10012; + public static final short CRYPTO_ILLEGAL_USE = 10008; + public static final short CRYPTO_ILLEGAL_VALUE = 10009; + public static final short CRYPTO_INVALID_INIT = 10010; + public static final short CRYPTO_NO_SUCH_ALGORITHM = 10011; + public static final short CRYPTO_UNINITIALIZED_KEY = 10012; //Generic Unknown error. - public static short GENERIC_UNKNOWN_ERROR = 10013; + public static final short GENERIC_UNKNOWN_ERROR = 10013; } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index b30e63c2..284a10c2 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -1672,6 +1672,7 @@ private void finishDecryptOperation(KMOperationState op, byte[] scratchPad) { Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0); if (op.getPadding() == KMType.PADDING_NONE && len != 256) KMException.throwIt(KMError.INVALID_INPUT_LENGTH); + System.out.println("Heap Index:"+repository.alloc((short)0)); len = op.getOperation() .finish( From 530cb6755addd46f0d7cd4598a1894dd023d7107 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 9 Feb 2021 18:27:03 +0530 Subject: [PATCH 2/5] Fixed the issue with RSA private and public key buffer while copying --- .../keymaster/KMAndroidSEProvider.java | 23 +- .../javacard/keymaster/KMJCardSimulator.java | 208 +++++++----------- .../javacard/keymaster/KMOperationImpl.java | 12 - .../javacard/test/KMFunctionalTest.java | 39 +--- .../javacard/keymaster/KMKeymasterApplet.java | 6 +- 5 files changed, 102 insertions(+), 186 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index 6a5a0671..78b90b57 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -112,6 +112,7 @@ public class KMAndroidSEProvider implements KMSEProvider { public static final byte KEYSIZE_128_OFFSET = 0x00; public static final byte KEYSIZE_256_OFFSET = 0x01; public static final short TMP_ARRAY_SIZE = 256; + private static final short RSA_KEY_SIZE = 256; public static final short CERT_CHAIN_MAX_SIZE = 2500;//First 2 bytes for length. final byte[] CIPHER_ALGS = { @@ -532,13 +533,27 @@ public void createAsymmetricKey(byte alg, byte[] privKeyBuf, short pubModStart, short pubModLength, short[] lengths) { switch (alg) { case KMType.RSA: + if (RSA_KEY_SIZE != privKeyLength || RSA_KEY_SIZE != pubModLength) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } KeyPair rsaKey = createRsaKeyPair(); RSAPrivateKey privKey = (RSAPrivateKey) rsaKey.getPrivate(); - lengths[0] = privKey.getExponent(privKeyBuf, privKeyStart); - lengths[1] = privKey.getModulus(pubModBuf, pubModStart); - if (lengths[0] > privKeyLength || lengths[1] > pubModLength) { + //Copy exponent. + Util.arrayFillNonAtomic(tmpArray, (short) 0, RSA_KEY_SIZE, (byte) 0); + lengths[0] = privKey.getExponent(tmpArray, (short)0); + if (lengths[0] > privKeyLength) CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } + Util.arrayFillNonAtomic(privKeyBuf, privKeyStart, privKeyLength, (byte)0); + Util.arrayCopyNonAtomic(tmpArray, (short)0, + privKeyBuf, (short)(privKeyStart + privKeyLength - lengths[0]), lengths[0]); + //Copy modulus + Util.arrayFillNonAtomic(tmpArray, (short) 0, RSA_KEY_SIZE, (byte) 0); + lengths[1] = privKey.getModulus(tmpArray, (short)0); + if (lengths[1] > pubModLength) + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + Util.arrayFillNonAtomic(pubModBuf, pubModStart, pubModLength, (byte)0); + Util.arrayCopyNonAtomic(tmpArray, (short)0, + pubModBuf, (short)(pubModStart + pubModLength - lengths[1]), lengths[1]); break; case KMType.EC: KeyPair ecKey = createECKeyPair(); diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index 6b0596ae..d97acc6d 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -72,6 +72,7 @@ public class KMJCardSimulator implements KMSEProvider { public static final short ENTROPY_POOL_SIZE = 16; // simulator does not support 256 bit aes keys public static final byte[] aesICV = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; private static final short CERT_CHAIN_MAX_SIZE = 2500;//First 2 bytes for length. + private static final short RSA_KEY_SIZE = 256; public static boolean jcardSim = false; @@ -166,9 +167,6 @@ public AESKey createAESKey(byte[] buf, short startOff, short length) { key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_256, false); key.setKey(buf, (short) startOff); } - // byte[] buffer = new byte[length]; - // Util.arrayCopyNonAtomic(buf, startOff, buffer, (short)0,length); - // print("AES Key", buffer); return key; } @@ -221,13 +219,27 @@ public void createAsymmetricKey(byte alg, byte[] privKeyBuf, short privKeyStart, byte[] pubModBuf, short pubModStart, short pubModLength, short[] lengths){ switch (alg){ case KMType.RSA: + if (RSA_KEY_SIZE != privKeyLength || RSA_KEY_SIZE != pubModLength) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } KeyPair rsaKey = createRsaKeyPair(); RSAPrivateKey privKey = (RSAPrivateKey) rsaKey.getPrivate(); - lengths[0] = privKey.getExponent(privKeyBuf,privKeyStart); - lengths[1] = privKey.getModulus(pubModBuf,pubModStart); - if(lengths[0] > privKeyLength || lengths[1] > pubModLength){ + //Copy exponent. + byte[] exp = new byte[RSA_KEY_SIZE]; + lengths[0] = privKey.getExponent(exp, (short)0); + if (lengths[0] > privKeyLength) CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } + Util.arrayFillNonAtomic(privKeyBuf, privKeyStart, privKeyLength, (byte)0); + Util.arrayCopyNonAtomic(exp, (short)0, + privKeyBuf, (short)(privKeyStart + privKeyLength - lengths[0]), lengths[0]); + //Copy modulus + byte[] mod = new byte[RSA_KEY_SIZE]; + lengths[1] = privKey.getModulus(mod, (short)0); + if (lengths[1] > pubModLength) + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + Util.arrayFillNonAtomic(pubModBuf, pubModStart, pubModLength, (byte)0); + Util.arrayCopyNonAtomic(mod, (short)0, + pubModBuf, (short)(pubModStart + pubModLength - lengths[1]), lengths[1]); break; case KMType.EC: KeyPair ecKey = createECKeyPair(); @@ -312,20 +324,6 @@ public short aesGCMEncrypt( if(keyLen != 32 && keyLen != 16){ CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); } - /*byte[] keyMaterial = new byte[key]; - short keySize = 16; - if(key.getSize() == 128){ - keyMaterial = new byte[16]; - }else if(key.getSize() == 256){ - keyMaterial = new byte[32]; - keySize = 32; - } - key.getKey(keyMaterial,(short)0); - - */ - - //print("KeyMaterial Enc", keyMaterial); - //print("Authdata Enc", authData, authDataStart, authDataLen); java.security.Key aesKey = new SecretKeySpec(keyBuf,keyStart,keyLen, "AES"); // Create the cipher javax.crypto.Cipher cipher = null; @@ -402,73 +400,67 @@ public boolean aesGCMDecrypt( short authDataLen, byte[] authTag, short authTagStart, - short authTagLen) { - //Create the sun jce compliant aes key - if(keyLen != 32 && keyLen != 16){ + short authTagLen) { + // Create the sun jce compliant aes key + if (keyLen != 32 && keyLen != 16) { CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); } - /*byte[] keyMaterial = new byte[16]; - short keySize = 16; - if(key.getSize() == 128){ - keyMaterial = new byte[16]; - }else if(key.getSize() == 256){ - keyMaterial = new byte[32]; - keySize = 32; - } - key.getKey(keyMaterial,(short)0); - - */ - //print("KeyMaterial Dec", keyMaterial); - //print("Authdata Dec", authData, authDataStart, authDataLen); - java.security.Key aesKey = new SecretKeySpec(keyBuf,keyStart,keyLen, "AES"); + java.security.Key aesKey = new SecretKeySpec(keyBuf, keyStart, keyLen, + "AES"); // Create the cipher - javax.crypto.Cipher cipher = null; - try { - cipher = javax.crypto.Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); - } catch (NoSuchProviderException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.INVALID_INIT); - } catch (NoSuchPaddingException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } - // Copy nonce - if(nonceLen != AES_GCM_NONCE_LENGTH){ - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } - byte[] iv = new byte[AES_GCM_NONCE_LENGTH]; - Util.arrayCopyNonAtomic(nonce,nonceStart,iv,(short)0,AES_GCM_NONCE_LENGTH); - // Init Cipher - GCMParameterSpec spec = new GCMParameterSpec(authTagLen * 8, nonce,nonceStart,AES_GCM_NONCE_LENGTH); - try { - cipher.init(javax.crypto.Cipher.DECRYPT_MODE, aesKey, spec); - } catch (InvalidKeyException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.INVALID_INIT); - } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); - } - // Create auth data - byte[] aad = new byte[authDataLen]; - Util.arrayCopyNonAtomic(authData,authDataStart,aad,(short)0,authDataLen); - cipher.updateAAD(aad); - // Append the auth tag at the end of data - byte[] inputBuf = new byte[(short)(encSecretLen + authTagLen)]; - Util.arrayCopyNonAtomic(encSecret,encSecretStart,inputBuf,(short)0,encSecretLen); - Util.arrayCopyNonAtomic(authTag,authTagStart,inputBuf,encSecretLen,authTagLen); - // Decrypt + javax.crypto.Cipher cipher = null; + try { + cipher = javax.crypto.Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); + } catch (NoSuchProviderException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.INVALID_INIT); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + // Copy nonce + if (nonceLen != AES_GCM_NONCE_LENGTH) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + byte[] iv = new byte[AES_GCM_NONCE_LENGTH]; + Util.arrayCopyNonAtomic(nonce, nonceStart, iv, (short) 0, + AES_GCM_NONCE_LENGTH); + // Init Cipher + GCMParameterSpec spec = new GCMParameterSpec(authTagLen * 8, nonce, + nonceStart, AES_GCM_NONCE_LENGTH); + try { + cipher.init(javax.crypto.Cipher.DECRYPT_MODE, aesKey, spec); + } catch (InvalidKeyException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.INVALID_INIT); + } catch (InvalidAlgorithmParameterException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); + } + // Create auth data + byte[] aad = new byte[authDataLen]; + Util.arrayCopyNonAtomic(authData, authDataStart, aad, (short) 0, + authDataLen); + cipher.updateAAD(aad); + // Append the auth tag at the end of data + byte[] inputBuf = new byte[(short) (encSecretLen + authTagLen)]; + Util.arrayCopyNonAtomic(encSecret, encSecretStart, inputBuf, (short) 0, + encSecretLen); + Util.arrayCopyNonAtomic(authTag, authTagStart, inputBuf, encSecretLen, + authTagLen); + // Decrypt short len = 0; - byte[] outputBuf = new byte[cipher.getOutputSize((short)inputBuf.length)]; + byte[] outputBuf = new byte[cipher.getOutputSize((short) inputBuf.length)]; try { - len = (short)(cipher.doFinal(inputBuf,(short)0,(short)inputBuf.length,outputBuf,(short)0)); - }catch(AEADBadTagException e){ + len = (short) (cipher.doFinal(inputBuf, (short) 0, + (short) inputBuf.length, outputBuf, (short) 0)); + } catch (AEADBadTagException e) { e.printStackTrace(); return false; - }catch (ShortBufferException e) { + } catch (ShortBufferException e) { e.printStackTrace(); CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); } catch (IllegalBlockSizeException e) { @@ -478,8 +470,8 @@ public boolean aesGCMDecrypt( e.printStackTrace(); CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); } - //Copy the decrypted data - Util.arrayCopyNonAtomic(outputBuf, (short)0,secret,secretStart,len); + // Copy the decrypted data + Util.arrayCopyNonAtomic(outputBuf, (short) 0, secret, secretStart, len); return true; } @@ -641,50 +633,7 @@ public KMOperation initAsymmetricOperation(byte purpose, byte alg, byte padding, CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); return null; } -/* - @Override - public short updateOperation(short opHandle, byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { - Object op = findOperation(opHandle); - if(op instanceof Signature ){ - ((Signature)op).update(inputDataBuf,inputDataStart,inputDataLength); - return 0; - }else{ - return ((KMCipher)op).update(inputDataBuf,inputDataStart,inputDataLength,outputDataBuf,outputDataStart); - } - } - @Override - public short finishOperation(short opHandle, byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { - Object op = findOperation(opHandle); - short ret = 0; - if(op instanceof Signature ){ - ret = ((Signature)op).sign(inputDataBuf,inputDataStart,inputDataLength,outputDataBuf,outputDataStart); - }else{ - ret = ((KMCipher)op).doFinal(inputDataBuf,inputDataStart,inputDataLength,outputDataBuf,outputDataStart); - } - removeOperation(opHandle); - return ret; - } - - @Override - public void abortOperation(short opHandle) { - removeOperation(opHandle); - } - - @Override - public void updateAAD(short opHandle, byte[] dataBuf, short dataStart, short dataLength) { - KMCipher aesGcm = (KMCipher) findOperation(opHandle); - aesGcm.updateAAD(dataBuf, dataStart, dataLength); - } - - @Override - public void getAESGCMOutputSize(short opHandle, short dataSize, short macLength) { - KMCipher aesGcm = (KMCipher) findOperation(opHandle); - aesGcm.getAesGcmOutputSize(dataSize, macLength); - } - */ - - public KMCipher createRsaDecipher(short padding, short digest, byte[] secret, short secretStart, short secretLength, byte[] modBuffer, short modOff, short modLength) { byte cipherAlg = mapCipherAlg(KMType.RSA, (byte)padding, (byte)0); @@ -783,12 +732,7 @@ public Signature createRsaSigner(short digest, short padding, byte[] secret, (padding == KMType.RSA_PKCS1_1_5_SIGN && digest == KMType.DIGEST_NONE)) { return createNoDigestSigner(padding,secret, secretStart, secretLength, modBuffer, modOff, modLength); - }/* - else if (padding == KMCipher.PAD_PKCS1_PSS) alg = Signature.ALG_RSA_SHA_256_PKCS1_PSS; - else if (padding == KMCipher.PAD_PKCS1) { - alg = Signature.ALG_RSA_SHA_256_PKCS1; - }else CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM); - */ + } Signature rsaSigner = Signature.getInstance((byte)alg, false); RSAPrivateKey key = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_2048, false); key.setExponent(secret,secretStart,secretLength); diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index 8379bfae..78c01302 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -41,21 +41,9 @@ public short update(byte[] inputDataBuf, short inputDataStart, short inputDataLe signature.update(inputDataBuf,inputDataStart,inputDataLength); return 0; } - - - private static void print(byte[] buf, short start, short length){ - StringBuilder sb = new StringBuilder(); - for(int i = start; i < (start+length); i++){ - sb.append(String.format("%02X", buf[i])) ; - //if((i-start)%16 == 0 && (i-start) != 0) sb.append(String.format("\n")); - } - System.out.println(sb.toString()); - } - @Override public short finish(byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { - print(inputDataBuf, inputDataStart, inputDataLength); return cipher.doFinal(inputDataBuf,inputDataStart,inputDataLength,outputDataBuf,outputDataStart); } diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index 3b0797ea..1e946df7 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -2092,37 +2092,6 @@ public short generateRandom(short upperBound) { return int_random; } - @Test - public void JCardTestRsaPkcs1() { - //Testing with Only Javacard APIs - byte[] message = { - 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, - 0x21 }; - for (int i = 0; i < 500; i++) { - byte[] out = new byte[256]; - byte[] dplain = new byte[256]; - KeyPair rsaKey = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048); - rsaKey.genKeyPair(); - Cipher rsaCipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false); - RSAPublicKey key = (RSAPublicKey) rsaKey.getPublic(); - rsaCipher.init(key, Cipher.MODE_ENCRYPT); - - short outlen = rsaCipher.doFinal(message, (short) 0, - (short) message.length, out, (short) 0); - Assert.assertEquals(outlen, 256); - - RSAPrivateKey privKey = (RSAPrivateKey) rsaKey.getPrivate(); - rsaCipher.init(privKey, Cipher.MODE_DECRYPT); - short d_outlen = rsaCipher.doFinal(out, (short) 0, outlen, dplain, - (short) 0); - Assert.assertEquals(d_outlen, message.length); - byte[] plain = new byte[d_outlen]; - Util.arrayCopyNonAtomic(dplain, (short) 0, plain, (short) 0, d_outlen); - - Assert.assertTrue(Arrays.equals(message, plain)); - } - } - @Test public void testVtsRsaPkcs1Success() { init(); @@ -2146,11 +2115,10 @@ public void testVtsRsaPkcs1Success() { KMType.RSA_PKCS1_1_5_ENCRYPT); byte[] cipherText2 = EncryptMessage(message, pkcs1Params, keyBlob); Assert.assertEquals((2048 / 8), cipherText2.length); - System.out.println("stage-2"); + // PKCS1 v1.5 randomizes padding so every result should be different. Assert.assertFalse(Arrays.equals(cipherText1, cipherText2)); - print(cipherText1, (short) 0, (short) cipherText1.length); pkcs1Params = getRsaParams(KMType.DIGEST_NONE, KMType.RSA_PKCS1_1_5_ENCRYPT); byte[] plainText = DecryptMessage(cipherText1, pkcs1Params, keyBlob); @@ -2171,7 +2139,6 @@ public void testVtsRsaPkcs1Success() { short ret = begin(KMType.DECRYPT, KMByteBlob.instance(keyBlob, (short) 0, (short) keyBlob.length), KMKeyParameters.instance(pkcs1Params), (short) 0); - System.out.println("stage-4"); // Get the operation handle. short opHandle = KMArray.cast(ret).get((short) 2); @@ -2179,14 +2146,12 @@ public void testVtsRsaPkcs1Success() { KMInteger.cast(opHandle).getValue(opHandleBuf, (short) 0, (short) opHandleBuf.length); opHandle = KMInteger.uint_64(opHandleBuf, (short) 0); - System.out.println("stage-5"); + short dataPtr = KMByteBlob.instance(cipherText1, (short) 0, (short) cipherText1.length); // Finish should return UNKNOWN_ERROR. ret = finish(opHandle, dataPtr, null, (short) 0, (short) 0, (short) 0, KMError.UNKNOWN_ERROR); - System.out.println("stage-6"); - System.out.println("Count of i:" + i); } cleanUp(); } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 284a10c2..61bcf931 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -538,6 +538,11 @@ private void resetData() { data[index] = KMType.INVALID_VALUE; index++; } + index = 0; + while (index < tmpVariables.length) { + tmpVariables[index] = KMType.INVALID_VALUE; + index++; + } } /** Sends a response, may be extended response, as requested by the command. */ public static void sendOutgoing(APDU apdu) { @@ -1672,7 +1677,6 @@ private void finishDecryptOperation(KMOperationState op, byte[] scratchPad) { Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0); if (op.getPadding() == KMType.PADDING_NONE && len != 256) KMException.throwIt(KMError.INVALID_INPUT_LENGTH); - System.out.println("Heap Index:"+repository.alloc((short)0)); len = op.getOperation() .finish( From d4928a79acb545126a2d637d013daf9cd921f5f9 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 9 Feb 2021 20:41:30 +0530 Subject: [PATCH 3/5] Added testDesEcbPkcs7PaddingCorrupted test function --- .../javacard/test/KMFunctionalTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index 1e946df7..2f6a9ba6 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -2092,6 +2092,50 @@ public short generateRandom(short upperBound) { return int_random; } + @Test + public void testDesEcbPkcs7PaddingCorrupted() { + init(); + short desKey = generateAesDesKey(KMType.DES, (short) 168, null, null, false); + short desKeyPtr = KMArray.cast(desKey).get((short) 1); + byte[] keyBlob = new byte[KMByteBlob.cast(desKeyPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(desKeyPtr).getBuffer(), KMByteBlob + .cast(desKeyPtr).getStartOff(), keyBlob, (short) 0, + (short) keyBlob.length); + + byte[] message = { + 0x61 }; + short desPkcs7Params = getAesDesParams(KMType.DES, KMType.ECB, + KMType.PKCS7, null); + byte[] cipherText1 = EncryptMessage(message, desPkcs7Params, keyBlob); + Assert.assertEquals(8, cipherText1.length); + Assert.assertFalse(Arrays.equals(message, cipherText1)); + + // Corrupt the cipher text. + ++cipherText1[(cipherText1.length / 2)]; + + // Decrypt operation + // Begin + desPkcs7Params = getAesDesParams(KMType.DES, KMType.ECB, KMType.PKCS7, null); + + short ret = begin(KMType.DECRYPT, + KMByteBlob.instance(keyBlob, (short) 0, (short) keyBlob.length), + KMKeyParameters.instance(desPkcs7Params), (short) 0); + // Get the operation handle. + short opHandle = KMArray.cast(ret).get((short) 2); + byte[] opHandleBuf = new byte[KMRepository.OPERATION_HANDLE_SIZE]; + KMInteger.cast(opHandle).getValue(opHandleBuf, (short) 0, + (short) opHandleBuf.length); + opHandle = KMInteger.uint_64(opHandleBuf, (short) 0); + + // Finish + short dataPtr = KMByteBlob.instance(cipherText1, (short) 0, + (short) cipherText1.length); + opHandle = KMInteger.uint_64(opHandleBuf, (short) 0); + ret = finish(opHandle, dataPtr, null, (short) 0, (short) 0, (short) 0, + KMError.INVALID_ARGUMENT); + cleanUp(); + } + @Test public void testVtsRsaPkcs1Success() { init(); From 182ca2621850b39e98624cb87c278fc77d787067 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Tue, 9 Feb 2021 23:30:58 +0530 Subject: [PATCH 4/5] Removed unused imports --- .../com/android/javacard/test/KMFunctionalTest.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index 2f6a9ba6..a6308513 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -17,8 +17,6 @@ package com.android.javacard.test; import com.android.javacard.keymaster.KMArray; -import com.android.javacard.keymaster.KMAttestationCert; -import com.android.javacard.keymaster.KMAttestationCertImpl; import com.android.javacard.keymaster.KMBoolTag; import com.android.javacard.keymaster.KMByteBlob; import com.android.javacard.keymaster.KMByteTag; @@ -41,20 +39,11 @@ import com.android.javacard.keymaster.KMRepository; import com.android.javacard.keymaster.KMType; import com.android.javacard.keymaster.KMVerificationToken; -//import com.licel.jcardsim.bouncycastle.crypto.Digest; import com.licel.jcardsim.smartcardio.CardSimulator; import com.licel.jcardsim.utils.AIDUtil; import javacard.framework.AID; import javacard.framework.Util; -import javacard.security.KeyBuilder; -import javacard.security.KeyPair; -import javacard.security.RSAPrivateKey; -import javacard.security.RSAPublicKey; -import javacard.security.Signature; -import javacardx.crypto.Cipher; - -import java.security.spec.PKCS8EncodedKeySpec; import java.util.Arrays; import java.util.Random; From c766d68fb5633950208254c015125b75087eb73c Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Wed, 10 Feb 2021 01:11:05 +0530 Subject: [PATCH 5/5] Removed unused/commented code. --- .../keymaster/KMAttestationCertImpl.java | 21 ---------------- .../android/javacard/keymaster/KMUtils.java | 23 ------------------ .../keymaster/KMAttestationCertImpl.java | 20 ---------------- .../android/javacard/keymaster/KMCipher.java | 24 ------------------- .../javacard/keymaster/KMCipherImpl.java | 2 -- .../javacard/keymaster/KMJCardSimulator.java | 5 ---- .../android/javacard/keymaster/KMUtils.java | 23 ------------------ .../javacard/keymaster/KMKeymasterApplet.java | 16 ------------- 8 files changed, 134 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 6025feef..637a2fba 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -127,7 +127,6 @@ public static KMAttestationCert instance(boolean rsaCert) { } private static void init() { - // if (repo == null) repo = KMRepository.instance(); stack = null; stackPtr = 0; certStart = 0; @@ -283,7 +282,6 @@ private static void pushTbsCert(boolean rsaCert) { pushBytes(X509Subject, (short) 0, (short) X509Subject.length); pushValidity(); // issuer - der encoded - // pushBytes(repo.getCertDataBuffer(), repo.getIssuer(), repo.getIssuerLen()); pushBytes( KMByteBlob.cast(issuer).getBuffer(), KMByteBlob.cast(issuer).getStartOff(), @@ -304,23 +302,6 @@ private static void pushTbsCert(boolean rsaCert) { private static void pushExtensions() { short last = stackPtr; - // byte keyusage = 0; - // byte unusedBits = 8; - /* - if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.SIGN, hwParams)) { - keyusage = (byte) (keyusage | keyUsageSign); - unusedBits = 7; - } - if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.WRAP_KEY, hwParams)) { - keyusage = (byte) (keyusage | keyUsageKeyEncipher); - unusedBits = 5; - } - if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.DECRYPT, hwParams)) { - keyusage = (byte) (keyusage | keyUsageDataEncipher); - unusedBits = 4; - } - - */ if (keyUsage != 0) pushKeyUsage(keyUsage, unusedBits); pushKeyDescription(); pushSequenceHeader((short) (last - stackPtr)); @@ -565,7 +546,6 @@ private static void pushTag(short tag) { private static void pushRoT() { short last = stackPtr; // verified boot hash - // pushOctetString(repo.verifiedBootHash, (short) 0, (short) repo.verifiedBootHash.length); pushOctetString( KMByteBlob.cast(verifiedHash).getBuffer(), KMByteBlob.cast(verifiedHash).getStartOff(), @@ -670,7 +650,6 @@ private static void pushEnumTag(short tagId, byte val) { private static void pushIntegerTag(short tagId, byte[] buf, short start, short len) { short last = stackPtr; pushInteger(buf, start, len); - // pushIntegerHeader((short) (last - stackPtr)); pushTagIdHeader(tagId, (short) (last - stackPtr)); } // Ignore leading zeros. Only Unsigned Integers are required hence if MSB is set then add 0x00 diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java index 7b4352f8..65e83415 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -347,29 +347,6 @@ public static void shiftRight(byte[] buf, short start) { } } - - // num1 must be greater then or equal to num2 and both must be positive - /*private short subtractIntegers(short num1, short num2) { - short buf = - repository.alloc((short)24); byte[] scratchPad = repository.getHeap(); - Util.arrayFillNonAtomic(scratchPad, buf, (short) 24, (byte) 0); - Util.arrayCopyNonAtomic(KMInteger.cast(num1).getBuffer(), - KMInteger.cast(num1).getStartOff(), scratchPad, - (short) (buf + 8 - KMInteger.cast(num1).length()), - KMInteger.cast(num1).length()); - Util.arrayCopyNonAtomic(KMInteger.cast(num2).getBuffer(), - KMInteger.cast(num2).getStartOff(), scratchPad, - (short) (buf + 16 - KMInteger.cast(num2).length()), - KMInteger.cast(num2).length()); - if (scratchPad[buf] < 0 || scratchPad[(short) (buf + 8)] < 0) - return KMType.INVALID_VALUE; - if (Util.arrayCompare(scratchPad, buf, scratchPad, (short) (buf + 8), - (short) 8) < 1) - return KMType.INVALID_VALUE; - subtract(scratchPad, buf, (short) (buf + 8), (short) (buf + 16)); - return KMInteger.uint_64(scratchPad, (short) (buf + 16)); - }*/ - public static void add(byte[] buf, short op1, short op2, short result) { byte index = 7; byte carry = 0; diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 5be20599..18e67e72 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -121,7 +121,6 @@ public static KMAttestationCert instance(boolean rsaCert) { } private static void init() { - // if (repo == null) repo = KMRepository.instance(); stack = null; stackPtr = 0; certStart = 0; @@ -277,7 +276,6 @@ private static void pushTbsCert(boolean rsaCert) { pushBytes(X509Subject, (short) 0, (short) X509Subject.length); pushValidity(); // issuer - der encoded - // pushBytes(repo.getCertDataBuffer(), repo.getIssuer(), repo.getIssuerLen()); pushBytes( KMByteBlob.cast(issuer).getBuffer(), KMByteBlob.cast(issuer).getStartOff(), @@ -298,23 +296,6 @@ private static void pushTbsCert(boolean rsaCert) { private static void pushExtensions() { short last = stackPtr; - // byte keyusage = 0; - // byte unusedBits = 8; - /* - if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.SIGN, hwParams)) { - keyusage = (byte) (keyusage | keyUsageSign); - unusedBits = 7; - } - if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.WRAP_KEY, hwParams)) { - keyusage = (byte) (keyusage | keyUsageKeyEncipher); - unusedBits = 5; - } - if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.DECRYPT, hwParams)) { - keyusage = (byte) (keyusage | keyUsageDataEncipher); - unusedBits = 4; - } - - */ if (keyUsage != 0) pushKeyUsage(keyUsage, unusedBits); pushKeyDescription(); pushSequenceHeader((short) (last - stackPtr)); @@ -559,7 +540,6 @@ private static void pushTag(short tag) { private static void pushRoT() { short last = stackPtr; // verified boot hash - // pushOctetString(repo.verifiedBootHash, (short) 0, (short) repo.verifiedBootHash.length); pushOctetString( KMByteBlob.cast(verifiedHash).getBuffer(), KMByteBlob.cast(verifiedHash).getStartOff(), diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java index 017a8398..3e67ed5e 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java @@ -16,30 +16,6 @@ package com.android.javacard.keymaster; public abstract class KMCipher { - /* - public static final byte CIPHER_RSA = 7; - public static final short PAD_PKCS1_OAEP = 9; - public static final short PAD_PKCS1_OAEP_SHA224 = 13; - public static final byte PAD_PKCS1_OAEP_SHA256 = 14; - public static final short PAD_PKCS1_OAEP_SHA384 = 15; - public static final short PAD_PKCS1_OAEP_SHA512 = 16; - public static final short PAD_NOPAD = 1; - public static final short PAD_PKCS1_PSS = 8; - public static final short PAD_NULL = 0; - public static final short PAD_PKCS7 = 31; // Not supported in javacard - public static final short ALG_DES_CBC_NOPAD = 1; - public static final short ALG_DES_ECB_NOPAD = 5; - public static final short ALG_AES_BLOCK_128_CBC_NOPAD= 13; - public static final short ALG_AES_BLOCK_128_ECB_NOPAD = 14; - public static final short ALG_AES_GCM = -13; - public static final short MODE_ENCRYPT = 2; - public static final short MODE_DECRYPT = 1; - public static final short PAD_PKCS1 = 7; - public static final short AES_BLOCK_SIZE = 16; - public static final short DES_BLOCK_SIZE = 8; - public static final short ALG_AES_CTR = -16; - - */ public static final short SUN_JCE = 0xE9; public abstract short doFinal(byte[] buffer, short startOff, short length, byte[] scratchPad, short i); diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java index 7a1df761..bc07be8d 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java @@ -30,7 +30,6 @@ public class KMCipherImpl extends KMCipher{ private short cipherAlg; private short padding; private short mode; - private boolean verificationFlag; private short blockMode; KMCipherImpl(Cipher c){ cipher = c; @@ -59,7 +58,6 @@ public short doFinal(byte[] buffer, short startOff, short length, byte[] scratch return (short)sunCipher.doFinal(buffer,startOff,length,scratchPad,i); } catch (AEADBadTagException e) { e.printStackTrace(); - verificationFlag = false; KMException.throwIt(KMError.VERIFICATION_FAILED); } catch (ShortBufferException e) { e.printStackTrace(); diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index d97acc6d..664ade77 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -156,7 +156,6 @@ public AESKey createAESKey(short keysize) { return createAESKey(rndNum, (short)0, (short)rndNum.length); } - // @Override public AESKey createAESKey(byte[] buf, short startOff, short length) { AESKey key = null; short keysize = (short)(length * 8); @@ -359,7 +358,6 @@ public short aesGCMEncrypt( // Create auth data byte[] aad = new byte[authDataLen]; Util.arrayCopyNonAtomic(authData,authDataStart,aad,(short)0,authDataLen); - // print("AAD", aad); cipher.updateAAD(aad); // Encrypt secret short len = 0; @@ -982,8 +980,6 @@ public KMCipher createAesGcmCipher(short mode, short tagLen, byte[] secret, shor //Create the sun jce compliant aes key byte[] keyMaterial = new byte[secretLength]; Util.arrayCopyNonAtomic(secret,secretStart,keyMaterial,(short)0,secretLength); - //print("KeyMaterial Enc", keyMaterial); - //print("Authdata Enc", authData, authDataStart, authDataLen); java.security.Key aesKey = new SecretKeySpec(keyMaterial,(short)0,keyMaterial.length, "AES"); // Create the cipher javax.crypto.Cipher cipher = null; @@ -1162,7 +1158,6 @@ public Signature createEcVerifier(short digest, byte[] pubKey, short pubKeyStart @Override public KMAttestationCert getAttestationCert(boolean rsaCert) { - //certBuilder.reset(); return KMAttestationCertImpl.instance(rsaCert); } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java index 7b4352f8..65e83415 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -347,29 +347,6 @@ public static void shiftRight(byte[] buf, short start) { } } - - // num1 must be greater then or equal to num2 and both must be positive - /*private short subtractIntegers(short num1, short num2) { - short buf = - repository.alloc((short)24); byte[] scratchPad = repository.getHeap(); - Util.arrayFillNonAtomic(scratchPad, buf, (short) 24, (byte) 0); - Util.arrayCopyNonAtomic(KMInteger.cast(num1).getBuffer(), - KMInteger.cast(num1).getStartOff(), scratchPad, - (short) (buf + 8 - KMInteger.cast(num1).length()), - KMInteger.cast(num1).length()); - Util.arrayCopyNonAtomic(KMInteger.cast(num2).getBuffer(), - KMInteger.cast(num2).getStartOff(), scratchPad, - (short) (buf + 16 - KMInteger.cast(num2).length()), - KMInteger.cast(num2).length()); - if (scratchPad[buf] < 0 || scratchPad[(short) (buf + 8)] < 0) - return KMType.INVALID_VALUE; - if (Util.arrayCompare(scratchPad, buf, scratchPad, (short) (buf + 8), - (short) 8) < 1) - return KMType.INVALID_VALUE; - subtract(scratchPad, buf, (short) (buf + 8), (short) (buf + 16)); - return KMInteger.uint_64(scratchPad, (short) (buf + 16)); - }*/ - public static void add(byte[] buf, short op1, short op2, short result) { byte index = 7; byte carry = 0; diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 61bcf931..abf6e670 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -520,7 +520,6 @@ private void processDeviceLockedCmd(APDU apdu) { data[VERIFICATION_TOKEN] = KMArray.cast(tmpVariables[0]).get((short) 1); validateVerificationToken(data[VERIFICATION_TOKEN], scratchPad); short verTime = KMVerificationToken.cast(data[VERIFICATION_TOKEN]).getTimestamp(); - // short lastDeviceLockedTime = KMInteger.uint_64(repository.deviceLockedTimestamp, (short)0); short lastDeviceLockedTime = repository.getDeviceTimeStamp(); if (KMInteger.compare(verTime, lastDeviceLockedTime) > 0) { Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 8, (byte) 0); @@ -3006,7 +3005,6 @@ private void importAESKey(byte[] scratchPad) { KMException.throwIt(KMError.IMPORT_PARAMETER_MISMATCH); } } else { - // add the key size to scratch pad // add the key size to scratchPad tmpVariables[5] = KMInteger.uint_16(KMByteBlob.cast(data[SECRET]).length()); tmpVariables[6] = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, tmpVariables[5]); @@ -3135,26 +3133,20 @@ private void processSetBootParamsCmd(APDU apdu) { receiveIncoming(apdu); byte[] scratchPad = apdu.getBuffer(); // Argument 1 OS Version - // short osVersionExp = KMIntegerTag.exp(KMType.UINT_TAG); tmpVariables[0] = KMInteger.exp(); // Argument 2 OS Patch level - // short osPatchExp = KMIntegerTag.exp(KMType.UINT_TAG); tmpVariables[1] = KMInteger.exp(); // Argument 3 Vendor Patch level tmpVariables[2] = KMInteger.exp(); // Argument 4 Boot Patch level tmpVariables[3] = KMInteger.exp(); // Argument 5 Verified Boot Key - // short bootKeyExp = KMByteBlob.exp(); tmpVariables[4] = KMByteBlob.exp(); // Argument 6 Verified Boot Hash - // short bootHashExp = KMByteBlob.exp(); tmpVariables[5] = KMByteBlob.exp(); // Argument 7 Verified Boot State - // short bootStateExp = KMEnum.instance(KMType.VERIFIED_BOOT_STATE); tmpVariables[6] = KMEnum.instance(KMType.VERIFIED_BOOT_STATE); // Argument 8 Device Locked - // short deviceLockedExp = KMEnum.instance(KMType.DEVICE_LOCKED); tmpVariables[7] = KMEnum.instance(KMType.DEVICE_LOCKED); // Array of expected arguments short argsProto = KMArray.instance((short) 8); @@ -3171,21 +3163,13 @@ private void processSetBootParamsCmd(APDU apdu) { //reclaim memory repository.reclaimMemory(bufferLength); - // short osVersionTagPtr = KMArray.cast(args).get((short) 0); tmpVariables[0] = KMArray.cast(args).get((short) 0); - // short osPatchTagPtr = KMArray.cast(args).get((short) 1); tmpVariables[1] = KMArray.cast(args).get((short) 1); - // short vendorPatchTagPtr = KMArray.cast(args).get((short) 2); tmpVariables[2] = KMArray.cast(args).get((short) 2); - // short BootPatchTagPtr = KMArray.cast(args).get((short) 3); tmpVariables[3] = KMArray.cast(args).get((short) 3); - // short verifiedBootKeyPtr = KMArray.cast(args).get((short) 4); tmpVariables[4] = KMArray.cast(args).get((short) 4); - // short verifiedBootHashPtr = KMArray.cast(args).get((short) 5); tmpVariables[5] = KMArray.cast(args).get((short) 5); - // short verifiedBootStatePtr = KMArray.cast(args).get((short) 6); tmpVariables[6] = KMArray.cast(args).get((short) 6); - // short deviceLockedPtr = KMArray.cast(args).get((short) 7); tmpVariables[7] = KMArray.cast(args).get((short) 7); if (KMByteBlob.cast(tmpVariables[4]).length() > KMRepository.BOOT_KEY_MAX_SIZE) { KMException.throwIt(KMError.INVALID_ARGUMENT);